!==============================================================================
!==============================================================================
!
! Copyright (C) 2014
!
! PARIS Parallel Robust Interface Simulator
! NEW VOF FUNCTIONS
!
! This file contains a few routines in FORTRAN 90 for standard
! calculations with the Volume-of-Fluid (VOF) method
!
! Author: Ruben Scardovelli, ruben.scardovelli@unibo.it
!
! GPL Licence
!
! This program is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! This program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program. If not, see .
!===============================================================================
! DESCRIPTION OF FUNCTION AL3DNEW:
! compute in the unit cube the plane constant alpha satisfying
! [nr]*[x] = nr1*x1 + nr2*x2 + nr3*x3 = alpha
! where the normal is pointing outward from the reference phase
! INPUT: normal coefficients in nr(3) and volume fraction cc
! NOTE : the normal coefficients MUST satisfy the relation |nr1|+|nr2|+|nr3|=1
!-------------------------------------------------------------------------------
FUNCTION AL3DNEW(nr,cc)
IMPLICIT NONE
REAL(8), INTENT(IN):: nr(3),cc
REAL(8) :: AL3DNEW
REAL(8) :: cch,c01,c02,c03,np1,np2,np3
REAL(8) :: m1,m2,m3,m12,numer,denom,p,pst,q,arc,csarc
REAL(8), PARAMETER :: athird=1.d0/3.d0
INTRINSIC DABS,DMIN1,DMAX1,DSQRT,DACOS,DCOS
np1 = DABS(nr(1)) ! need positive coefficients
np2 = DABS(nr(2))
np3 = DABS(nr(3))
m1 = DMIN1(np1,np2) ! order positive coefficients
m3 = DMAX1(np1,np2)
if (np3 < m1) then
m2 = m1
m1 = np3
else if (np3 >= m3) then
m2 = m3
m3 = np3
else
m2 = np3
endif
cch = DMIN1(cc,1.d0-cc) ! limit to: 0 < cch < 1/2
denom = DMAX1(6.d0*m1*m2*m3,1.d-50) ! get cch ranges
c01 = m1*m1*m1/denom
c02 = c01 + 0.5d0*(m2-m1)/m3
m12 = m1 + m2
if (m12 <= m3) then
c03 = 0.5d0*m12/m3
else
numer = m3*m3*(3.d0*m12-m3) + m1*m1*(m1-3.d0*m3) + m2*m2*(m2-3.d0*m3)
c03 = numer/denom
endif
! 1: C<=C1; 2: C1<=C<=C2; 3: C2<=C<=C3; 4: C3<=C<=1/2 (a: m12<=m3; b: m3 0.5d0) AL3DNEW = 1.d0 - AL3DNEW
! compute alpha for the incoming coefficients
AL3DNEW = AL3DNEW + DMIN1(0.d0,nr(1)) + DMIN1(0.d0,nr(2)) + DMIN1(0.d0,nr(3))
END FUNCTION AL3DNEW
!===============================================================================
! DESCRIPTION OF FUNCTION CC3DNEW:
! compute in the unit cube the volume cut by the plane
! [nr]*[x] = nr1*x1 + nr2*x2 + nr3*x3 = alpha
! where the normal is pointing outward from the reference phase
! INPUT: normal coefficients in nr(3) and plane constant alpha
! NOTE : the normal coefficients MUST satisfy the relation |nr1|+|nr2|+|nr3|=1
!-------------------------------------------------------------------------------
FUNCTION CC3DNEW(nr,alpha)
IMPLICIT NONE
REAL(8), INTENT(IN):: nr(3),alpha
REAL(8) :: CC3DNEW
REAL(8) :: al,alh,np1,np2,np3,m1,m2,m3,m12,mm,denom,top
INTRINSIC DMAX1,DMIN1,DABS
np1 = DABS(nr(1)) ! need positive coefficients
np2 = DABS(nr(2))
np3 = DABS(nr(3))
m1 = DMIN1(np1,np2) ! order positive coefficients
m3 = DMAX1(np1,np2)
if (np3 < m1) then
m2 = m1
m1 = np3
else if (np3 >= m3) then
m2 = m3
m3 = np3
else
m2 = np3
endif
al = alpha + DMAX1(0.d0,-nr(1))+DMAX1(0.d0,-nr(2))+DMAX1(0.d0,-nr(3))
al = DMAX1(0.d0,DMIN1(1.d0,al)) ! safe limits
alh = DMIN1(al,1.d0-al) ! limit to: 0 < alh < 1/2
m12 = m1 + m2
mm = DMIN1(m12,m3)
denom = DMAX1(6.d0*m1*m2*m3,1.0d-50)
! 1: al<=m1; 2: m1<=al<=m2; 3: m2<=al<=mm; 4: mm<=al<=1/2 (a:m12<=m3; b:m3 0.5d0) CC3DNEW = 1.d0 - CC3DNEW
END FUNCTION CC3DNEW
!===============================================================================
! DESCRIPTION OF FUNCTION FL3DNEW:
! compute in the right hexahedron starting at (x01,x02,x03) and of sides
! (dx1,dx2,dx3) the volume cut by the plane
! [nr]*[x] = nr1*x1 + nr2*x2 + nr3*x3 = alpha
! INPUT: normal coefficients in nr(3), plane constant alpha, starting
! point x0(3), sides dx(3)
!-------------------------------------------------------------------------------
FUNCTION FL3DNEW(nr,alpha,x0,dx)
IMPLICIT NONE
REAL(8), INTENT(IN):: nr(3),x0(3),dx(3),alpha
REAL(8) :: FL3DNEW
REAL(8) :: al,almax,alh,np1,np2,np3,m1,m2,m3,m12,mm,denom,frac,top
INTRINSIC DMAX1,DMIN1,DABS
! move origin to x0
al = alpha - nr(1)*x0(1) - nr(2)*x0(2) - nr(3)*x0(3)
! reflect the figure when negative coefficients
al = al + DMAX1(0.d0,-nr(1)*dx(1)) + DMAX1(0.d0,-nr(2)*dx(2)) &
+ DMAX1(0.d0,-nr(3)*dx(3))
np1 = DABS(nr(1)) ! need positive coefficients
np2 = DABS(nr(2))
np3 = DABS(nr(3))
almax = np1*dx(1) + np2*dx(2) + np3*dx(3)
al = DMAX1(0.d0,DMIN1(1.d0,al/almax)) !get new al within safe limits
alh = DMIN1(al,1.d0-al) ! limit to: 0 < alh < 1/2
! normalized equation: m1*y1 + m2*y2 + m3*y3 = alh, with m1 <= m2 <= m3
np1 = np1/almax;
np2 = np2/almax;
np3 = np3/almax;
m1 = DMIN1(np1*dx(1),np2*dx(2)) ! order coefficients
m3 = DMAX1(np1*dx(1),np2*dx(2))
top = np3*dx(3)
if (top < m1) then
m2 = m1
m1 = top
else if (top >= m3) then
m2 = m3
m3 = top
else
m2 = top
endif
m12 = m1 + m2
mm = DMIN1(m12,m3)
denom = DMAX1(6.d0*m1*m2*m3,1.0d-50)
! 1: al<=m1; 2: m1<=al<=m2; 3: m2<=al<=mm; 4: mm<=al<=1/2 (a:m12<=m3; b:m3= m3) then
m2 = m3
m3 = np3
else
m2 = np3
endif
cch = DMIN1(cc,1.d0-cc) ! limit to: 0 < cch < 1/2
ccr = DMAX1(cch,cmin) ! full and empty neighboring cells
denom = DMAX1(2.d0*m1*m2*m3,1.d-50) ! get cch ranges
c01 = m1*m1*m1/(3.d0*denom)
c02 = c01 + 0.5d0*(m2-m1)/m3
m12 = m1 + m2
if (m12 <= m3) then
c03 = 0.5d0*m12/m3
else
numer = m3*m3*(3.d0*m12-m3) + m1*m1*(m1-3.d0*m3) + m2*m2*(m2-3.d0*m3)
c03 = numer/(3.d0*denom)
endif
c00 = DSQRT(m1*m1 + m2*m2 + m3*m3)
! 1: C<=C1; 2: C1<=C<=C2; 3: C2<=C<=C3; 4: C3<=C<=1/2 (a: m12<=m3; b: m3= m3) then
m2 = m3
m3 = np3
ind(2) = ind(3)
ind(3) = 3
else
m2 = np3
ind(2) = 3
endif
! TEMPORARY - Stanley: not working for corner full/empty cell (cc=1,m1=0,m2=m3=0.5)
if ( cc == 1.d0 .or. cc == 0.d0 ) then
cch = cmin
else
cch = DMIN1(cc,1.d0-cc) ! limit to: 0 < cch < 1/2
end if ! cc
! END TEMPOARY
! cch = DMIN1(cc,1.d0-cc) ! limit to: 0 < cch < 1/2
ccr = DMAX1(cch,cmin) ! full and empty neighboring cells
denom = DMAX1(6.d0*m1*m2*m3,1.d-50) ! get cch ranges
c01 = m1*m1*m1/denom
c02 = c01 + 0.5d0*(m2-m1)/m3
m12 = m1 + m2
if (m12 <= m3) then
c03 = 0.5d0*m12/m3
else
numer = m3*m3*(3.d0*m12-m3) + m1*m1*(m1-3.d0*m3) + m2*m2*(m2-3.d0*m3)
c03 = numer/denom
endif
! 1: C<=C1; 2: C1<=C<=C2; 3: C2<=C<=C3; 4: C3<=C<=1/2 (a: m12<=m3; b: m3 0.5d0) then
ctd0(1) = 1.d0 - ctd0(1)
ctd0(2) = 1.d0 - ctd0(2)
ctd0(3) = 1.d0 - ctd0(3)
endif
! get correct indexing
xc0(ind(1)) = ctd0(1)
xc0(ind(2)) = ctd0(2)
xc0(ind(3)) = ctd0(3)
! take care of negative coefficients
if (nr(1) < 0.d0) xc0(1) = 1.d0 - xc0(1)
if (nr(2) < 0.d0) xc0(2) = 1.d0 - xc0(2)
if (nr(3) < 0.d0) xc0(3) = 1.d0 - xc0(3)
END SUBROUTINE CENT3D
!=================================================================================================
! ****** 1 ******* 2 ******* 3 ******* 4 ******* 5 ******* 6 ******* 7 *
! PROGRAM TO FIND alpha IN: m1 x1 + m2 x2 + m3 x3 = alpha,
! GIVEN m1+m2+m3=1 (all > 0) AND THE VOLUMETRIC FRACTION cc
! ****** 1 ******* 2 ******* 3 ******* 4 ******* 5 ******* 6 ******* 7 *
function al3dOLD(b1,b2,b3,cc)
!***
implicit none
real(8) m1,m2,m3,cc,b1,b2,b3,tmp,pr,ch,mm,m12
real(8) p,p12,q,teta,cs,al3dOLD
real(8) untier,v1,v2,v3
parameter (untier=1.d0/3.d0)
intrinsic dmax1,dmin1,dsqrt,dacos,dcos
!***
! (1) order coefficients: m1