!============================================================================== !============================================================================== ! ! 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