Subroutine to solve a FE_FILM
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(FE_FILM), | intent(inout) | :: | fe_f | FE film data type |
||
type(MAT_SOLV), | intent(inout) | :: | mat | matrices for solving |
||
real(kind=R8), | intent(in), | dimension(MAX_NNC) | :: | bc | boundary conditions at the corners |
|
logical(kind=I4), | intent(in), | optional | :: | flag_ass | optional flag for assembly |
subroutine solve_FE_film(fe_f, mat, bc, flag_ass)
implicit none
type(FE_FILM), intent(inout) :: fe_f !! *FE film data type*
type(MAT_SOLV), intent(inout) :: mat !! *matrices for solving*
real(kind=R8), intent(in ), dimension(MAX_NNC) :: bc !! *boundary conditions at the corners*
logical(kind=I4), intent(in ), optional :: flag_ass !! *optional flag for assembly*
logical(kind=I4) :: decomp
integer(kind=I4) :: ass_c, i, it, e
logical(kind=I4) :: conv
real(kind=R8) :: error
integer(kind=I4), dimension(2) :: compt
! solution parameters
ass_c = ASS
if (present(flag_ass)) then
if (.not.flag_ass) ass_c = NO_ASS
endif
decomp = (ass_c == ASS)
! apply boundary conditions
if (BC_SPLINE) then
call apply_bc_FE_film(fe_f = fe_f, &
bc = bc)
else
call apply_bc_FE_film_simple(fe_f = fe_f, &
bc = bc)
endif
if (VERBOSE >= 20) write(OPU,*) 'bc applied'
! update fluid properties
do i = 1, fe_f%m%n
fe_f%vn(i, RHO_N) = fe_f%data_f%fl%rho( fe_f%vn(i, P_N) , fe_f%vn(i, T_N))
fe_f%vn(i, DRHODP_N) = fe_f%data_f%fl%drhodp(fe_f%vn(i, P_N) , fe_f%vn(i, T_N))
enddo
if (VERBOSE >= 20) write(OPU,*) 'fluid properties updated'
if (mat%first) then
mat%nn = fe_f%m%n
mat%ne = fe_f%m%ne
call solve_syst(mat = mat, &
step = 'ini')
if (VERBOSE >= 10) write(OPU,*) 'Matrix initialized, thread ', omp_get_thread_num()
! matrices allocation
compt(:) = 0
do e = 1, fe_f%m%ne
compt(1) = compt(1) +fe_f%m%el_n(e) ! for each element, the number of lines is added
do i = 1, fe_f%m%el_t(e)
compt(2) = compt(2) + fe_f%m%el_t(e) ! " ", for each node, the number of contributions is added
enddo
enddo
mat%nvar = compt(1)
mat%nt = compt(2)
if (.not.allocated(mat%eltvar)) allocate( mat%eltvar(mat%nvar ) )
if (.not.allocated(mat%a_elt )) allocate( mat%a_elt( mat%nt ) )
if (.not.allocated(mat%eltptr)) allocate( mat%eltptr(mat%ne +1 ) )
endif
! check of precomputed tables allocation
if (.not.allocated(fe_f%prc%vcal)) call init_prc_tab(fe_f)
! convergence is false at zero iteration
conv = .false.
it = 0
! solution loop
do
if (VERBOSE >= 20) write(OPU,*) ' Loop FE ', it
if (conv) exit
! assembly of the system
call assembly_FE_film_reynolds(fe_f, mat, ass_c)
if (VERBOSE >= 30) write(OPU,*) ' System assembled, thread ', omp_get_thread_num()
if (ass_c == ASS) then
! some stuff can be saved here, provided the reloading of jptr, irow, ... (instead of convert_matrice_format)
call convert_matrice_format(mat)
if (VERBOSE >= 30) write(OPU,*) ' Matrix converted, thread ', omp_get_thread_num()
endif
if (mat%first) then
call solve_syst(mat = mat, &
step = 'ana')
mat%first = .false.
if (VERBOSE >= 10) write(OPU,*) ' Matrix analyzed, thread ', omp_get_thread_num()
endif
! solution of the system
if (ass_c == ASS) then
call solve_syst(mat = mat, &
step = 'fac')
if (VERBOSE >= 30) write(OPU,*) ' Matrix factorized, thread ', omp_get_thread_num()
endif
call solve_syst(mat = mat, &
step = 'sol')
if (VERBOSE >= 30) write(OPU,*) ' System solved, thread ', omp_get_thread_num()
if (ass_c == ASS) then
call solve_syst(mat = mat, &
step = 'fre')
if (VERBOSE >= 30) write(OPU,*) ' Matrix factors freed, thread ', omp_get_thread_num()
endif
! error computation
error = (sum(mat%x ** 2) / sum(fe_f%vn(:, P_N) ** 2)) ** (0.5_R8)
it = it + 1
if (VERBOSE >= 20) write(OPU,*) ' Error ', error
! convergence check
if (error <= fe_f%num_p%eps) conv = .true.
! update of variables
if (fe_f%data_f%fl%fluid_type == MIXT) then
do i = 1, fe_f%m%n
if (mat%x(i) < 0.) then
fe_f%vn(i, RHO_N) = fe_f%vn(i, RHO_N) + fe_f%vn(i, DRHODP_N) * mat%x(i) * fe_f%num_p%relax
if (fe_f%vn(i, RHO_N) < 0.) then
fe_f%vn(i, P_N) = fe_f%data_f%fl%P_0/100
else
fe_f%vn(i, P_N) = fe_f%data_f%fl%pres( fe_f%vn(i, RHO_N), & !
fe_f%vn(i, T_N) )
endif
else
fe_f%vn(i, P_N) = fe_f%vn(i, P_N) + mat%x(i) * fe_f%num_p%relax
endif
enddo
else
fe_f%vn(:, P_N) = fe_f%vn(:, P_N) + mat%x * fe_f%num_p%relax
endif
! check pressure
if ( fe_f%data_f%fl%fluid_type == GP ) then
if (minval(fe_f%vn(:, P_N)) < 0._R8) then
if (VERBOSE >= 30) write(OPU,*) 'P negative'
endif
where (fe_f%vn(:, P_N) < 0._R8) fe_f%vn(:, P_N) = fe_f%data_f%fl%p_0 / 1.e3_R8
endif
do i = 1, fe_f%m%n
fe_f%vn(i, RHO_N) = fe_f%data_f%fl%rho( fe_f%vn(i, P_N) , fe_f%vn(i, T_N))
fe_f%vn(i, DRHODP_N) = fe_f%data_f%fl%drhodp(fe_f%vn(i, P_N) , fe_f%vn(i, T_N))
enddo
if (it >= fe_f%num_p%it_max) then
conv = .true.
if (VERBOSE >= 20) write(OPU,*) 'maximum number of iteration reached before convergence'
endif
enddo
return
endsubroutine solve_FE_film