A SOURCE CODE
A.5 Module maths_funcs2
This module contains a number of different subroutines and functions used in the program.
Firstly, the following is an overview of the module with the names of all functions and subroutines defined, along with the call variables in each case.
module maths_funcs2
subroutine cylinder(norm_vec,corner_pos,diam,fraction,distance) ...
end function normal_component
real function surface_area(span1,span2,span3,span4) ...
end function surface_area end module maths_funcs
In more detail, the contents of each of these routines are shown below.
A.5.1 real function surface_reduction
real function surface_reduction(d,velocity, dens)
!d is in units of projectile radii
! STATIC EXPRESSION FOR THE REDUCTION OF PRESSURE AS FUNCTION OF DISTANCE
! TO FREE BOUNDARIES use static_constants
surface_reduction=3*log(d)/static3 end if
! DYNAMIC SPHERICAL CAVITY EXPANSION
!!$ use constants_def
!!$ real :: d, velocity, dens, dens2
!!$
!!$ dens2=dens/2
!!$ if (plastic_boundary<=d) then
!!$ d=1/d
!!$ surface_reduction=(log_constant-&
!!$ red_yld*(plastic_boundary**3)*(d**3)+&
!!$ (dens2*velocity**2)*(3+d**4-4*d))/&
!!$ (log_constant+3*dens2*(velocity**2))
!!$ else
!!$ surface_reduction=(3*red_yld*log(d)+&
!!$ dens2*velocity*velocity*(3+1/(d**4)-4/d))/&
!!$ (log_constant+3*dens2*velocity*velocity)
!!$ end if
if (surface_reduction>1.0) surface_reduction=1.0 if (surface_reduction<0.0) surface_reduction=0.0 return
end function surface_reduction
A.5.2 subroutine unit_normal
implicit none
real, dimension(1:3), intent(in) :: vec1,vec2
real, dimension(1:3), intent(inout) :: result_vector real :: length_vec
result_vector(1)=vec1(2)*vec2(3)-vec1(3)*vec2(2) result_vector(2)=vec1(3)*vec2(1)-vec1(1)*vec2(3) result_vector(3)=vec1(1)*vec2(2)-vec1(2)*vec2(1)
length_vec=sqrt(result_vector(1)**2+result_vector(2)**2+&
result_vector(3)**2)
result_vector=result_vector/length_vec return
end subroutine unit_normal
A.5.3 subroutine cube
This subroutine calculates the smearing factor and the distance from free boundaries in the case of a prism-shaped target. The smearing factor is used to reduce the pressure on a cell face when that cell is only partially embedded in the target. The factor is calculated in the simplest possible way: when only one node is inside the target, the factor is 0.25, when two nodes are inside it is 0.5, and so on.
subroutine cube(norm_vec, nodes, diam, fraction, distance) use geometry
!The variables front, left, right, top etc refers to the target as seen along
!the positive z-axis. These variables are defined in the module.
implicit none
real, dimension(1:3), intent(in) :: norm_vec real, dimension(1:12), intent(in) :: nodes real, intent(in) :: diam
real, intent(out) :: fraction, distance integer :: no_nodes, i
real, dimension(1:3) :: distance_vec
real :: distance, nodex, nodey, nodez, minimum, maximum
!Check how many nodes are within the target, compute fraction no_nodes=0
accuracy=0.0 distance_vec=0.0
do i=0,3!The target is _always_ along coordinate axes nodex=nodes(i*3+1)
distance_vec(1)=distance_vec(1)+nodex distance_vec(2)=distance_vec(2)+nodey distance_vec(3)=distance_vec(3)+nodez
end do!distance_vec is now the vector sum of all four corner node positions
!relative to the absolute coordinate system in the calculation distance_vec=distance_vec/4
nodex=distance_vec(1) nodey=distance_vec(2)
nodez=distance_vec(3)!calculation of geometric mean of cell face.
if (no_nodes>0) then
!Binaersoek-algoritmen maximum=100.0*diam minimum=0.0
distance_vec=maximum*norm_vec
if (nodex+distance_vec(1)<left .and. nodex+distance_vec(1)>right&
.and. nodey+distance_vec(2)<top .and. &
This subroutine only needs two geometry inputs: the front and the rear faces of the target. It calculates the shortest distance to the rear face, but only after enough time has passed that elastic waves can travel across the target thickness and back to the projectile. It also calculates the shortest distance to the front face for oblique impacts. The target is infinite in the other two directions.
subroutine perforation(norm_vec, nodes, present_time, snd_spd, &
diam, fraction, distance) use geometry
!The variables front, left, right, top etc refers to the target as seen
!along the positive z-axis. These variables are defined in the module.
implicit none
real, dimension(1:3), intent(in) :: norm_vec real, dimension(1:12), intent(in) :: nodes real, intent(in) :: diam, present_time, snd_spd real, intent(out) :: fraction, distance
integer :: no_nodes, i
real, dimension(1:3) :: distance_vec
real :: distance, nodex, nodey, nodez, minimum, maximum
!Check how many nodes are within the target, compute fraction no_nodes=0
distance_vec=0.0
do i=0,3!The target is _always_ along coordinate axes nodex=nodes(i*3+1)
nodey=nodes(i*3+2)
distance_vec(1)=distance_vec(1)+nodex distance_vec(2)=distance_vec(2)+nodey distance_vec(3)=distance_vec(3)+nodez end do
!distance_vec is now the vector sum of all four corner node positions
!relative to the absolute coordinate system in the calculation distance_vec=distance_vec/4
nodex=distance_vec(1) nodey=distance_vec(2)
nodez=distance_vec(3)!calculation of geometric mean of cell face.
if (no_nodes>0) then
end subroutine perforation
A.5.5 subroutine cylinder
In case of a cylindrical target, the following subroutine is needed:
subroutine cylinder(norm_vec, nodes, diam, fraction, distance) use geometry
!The radius is the radius of the cylindrical target. The axis is along
!the positive z-axis, through the origin (x=0 y=0). These variables are
!defined in the module.
implicit none
real, dimension(1:3), intent(in) :: norm_vec real, dimension(1:12), intent(in) :: nodes real, intent(in) :: diam
real, intent(out) :: fraction, distance integer :: no_nodes, i
real, dimension(1:3) :: distance_vec
real :: distance, nodex, nodey, nodez, minimum, maximum, act_rad !Check how many nodes are within the target, compute fraction no_nodes=0
distance_vec=0.0
do i=0,3!The target is _always_ along coordinate axes nodex=nodes(i*3+1)
nodey=nodes(i*3+2) nodez=nodes(i*3+3)
act_rad=nodex**2+nodey**2
if (act_rad<radius**2 .and. nodez>front .and. nodez<rear) then no_nodes=no_nodes+1
end if
distance_vec(1)=distance_vec(1)+nodex distance_vec(2)=distance_vec(2)+nodey distance_vec(3)=distance_vec(3)+nodez
end do!distance_vec is now the vector sum of all four corner node positions
!relative to the absolute coordinate system in the calculation distance_vec=distance_vec/4
nodex=distance_vec(1) nodey=distance_vec(2)
nodez=distance_vec(3)!calculation of geometric mean of cell face.
if (no_nodes>0) then maximum=100.0*diam
minimum=0.0
distance_vec=maximum*norm_vec
act_rad=(nodex+distance_vec(1))**2+(nodey+distance_vec(2))**2 if (act_rad<radius**2 .and. &
act_rad=(nodex+distance_vec(1))**2+(nodey+distance_vec(2))**2 if (act_rad<radius**2 .and. &
end subroutine cylinder
A.5.6 subroutine sphere
Finally, the same calculations are performed for a spherical target using the subroutine sphere:
subroutine sphere(norm_vec, nodes, diam, fraction, distance) use geometry
!The radius is the radius of the spherical target. The variable is defined in
!the module. The centre of the sphere is at (x=left, y=top, z=front).
implicit none
real, dimension(1:3), intent(in) :: norm_vec real, dimension(1:12), intent(in) :: nodes real, intent(in) :: diam
real, intent(out) :: fraction, distance integer :: no_nodes, i
real, dimension(1:3) :: distance_vec
real :: distance, nodex, nodey, nodez, minimum, maximum, act_rad !Check how many nodes are within the target, compute fraction no_nodes=0
distance_vec=0.0
do i=0,3!The target is _always_ along coordinate axes nodex=nodes(i*3+1)
nodey=nodes(i*3+2) nodez=nodes(i*3+3)
act_rad=(nodex-left)**2+(nodey-top)**2+(nodez-front)**2 if (act_rad<=radius**2) then
no_nodes=no_nodes+1 end if
distance_vec(1)=distance_vec(1)+nodex distance_vec(2)=distance_vec(2)+nodey distance_vec(3)=distance_vec(3)+nodez
end do!distance_vec is now the vector sum of all four corner node positions
!relative to the absolute coordinate system in the calculation distance_vec=distance_vec/4
nodex=distance_vec(1) nodey=distance_vec(2)
nodez=distance_vec(3)!calculation of geometric mean of cell face.
if (no_nodes>0) then maximum=100.0*diam
minimum=0.0
distance_vec=maximum*norm_vec
act_rad=(nodex+distance_vec(1))**2+(nodey+distance_vec(2))**2+&
(nodez+distance_vec(3))**2
act_rad=(nodex+distance_vec(1))**2+(nodey+distance_vec(2))**2+&
(nodez+distance_vec(3))**2
return
end subroutine sphere
A.5.7 real function normal_component
implicit none
real, dimension(1:3),intent(in) :: vec1,unit_vec
normal_component=vec1(1)*unit_vec(1)+vec1(2)*unit_vec(2)+&
vec1(3)*unit_vec(3) return
end function normal_component
A.5.8 real function surface_area
implicit none
real, dimension(1:3),intent(in) :: span1,span2,span3,span4 real :: area
area=sqrt((span1(2)*span2(3)-span1(3)*span2(2))**2+&
(span1(3)*span2(1)-span1(1)*span2(3))**2+&
(span1(1)*span2(2)-span1(2)*span2(1))**2)+&
sqrt((span3(2)*span4(3)-span3(3)*span4(2))**2+&
(span3(3)*span4(1)-span3(1)*span4(3))**2+&
(span3(1)*span4(2)-span3(2)*span4(1))**2) surface_area=area/2
return
end function surface_area