! Copyright (c) 2015 Nikhil Anand <nikhil.anand@uni-siegen.de> ! Copyright (c) 2015-2017, 2020 Peter Vitt <peter.vitt2@uni-siegen.de> ! Copyright (c) 2016-2017 Kannan Masilamani <kannan.masilamani@uni-siegen.de> ! Copyright (c) 2016 Verena Krupp <verena.krupp@uni-siegen.de> ! Copyright (c) 2016 Harald Klimach <harald.klimach@uni-siegen.de> ! Copyright (c) 2016-2017 Tobias Girresser <tobias.girresser@student.uni-siegen.de> ! Copyright (c) 2017 Daniel PetrĂ³ <daniel.petro@student.uni-siegen.de> ! ! Permission to use, copy, modify, and distribute this software for any ! purpose with or without fee is hereby granted, provided that the above ! copyright notice and this permission notice appear in all copies. ! ! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES ! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! **************************************************************************** ! module atl_eqn_filNvrStk_var_module use, intrinsic :: iso_c_binding, only: c_loc, c_f_pointer, c_ptr use env_module, only: rk, labelLen use tem_varSys_module, only: tem_varSys_type, & & tem_varSys_init, & & tem_varSys_append_stateVar, & & tem_varSys_append_derVar, & & tem_varSys_proc_point, & & tem_varSys_proc_element, & & tem_varSys_proc_setparams, & & tem_varSys_proc_getparams, & & tem_varSys_proc_setupIndices, & & tem_varSys_proc_getValOfIndex use tem_grow_array_module, only: init, append, truncate use tem_dyn_array_module, only: init, append, truncate, & & PositionOfVal use tem_logging_module, only: logUnit use tem_varMap_module, only: tem_possible_variable_type, & & init, append use tem_aux_module, only: tem_abort use tem_operation_var_module, only: tem_divideVecByScal_forPoint, & & tem_divideVecByScal_fromIndex, & & tem_opVar_setupIndices, & & tem_get_new_varSys_data_ptr use tem_varSys_module, only: tem_varSys_type use tem_time_module, only: tem_time_type use ply_oversample_module, only: ply_convert2oversample, & & ply_convertFromoversample use ply_poly_project_module, only: ply_poly_project_type, & & assignment(=), & & ply_poly_project_n2m, & & ply_poly_project_m2n use ply_leg_diff_module, only: ply_calcDiff_leg_2d use atl_equation_module, only: atl_equations_type use atl_source_types_module, only: atl_eqn_sourceMap_type use atl_eqn_filNvrStk_derive_module, only: atl_Rans_pressure_getElement, & & atl_Rans_pressure_getPoint use atl_varSys_module, only: atl_varSys_solverData_type, & & atl_varSys_data_type, & & atl_varSys_getStateForElement, & & atl_varSys_getStateForPoint, & & atl_get_new_varSys_data_ptr, & & atl_varSys_setupStateIndices, & & atl_varSys_getStateValofIndex use atl_operator_module, only: atl_op_divideVecByScal_forElement, & & atl_opVar_setupIndices use atl_source_types_module, only: atl_source_op_type use atl_cube_elem_module, only: atl_cube_elem_type implicit none private public :: atl_init_rans_vars public :: atl_init_rans_2d_vars public :: atl_append_rans_consVars public :: atl_append_rans_primVars public :: atl_init_filNvrStk_sourceTerms public :: atl_get_pointwise_velocity_gradient_2D public :: atl_get_pointwise_visc_stress_tensor_2D public :: atl_get_lower_bound_turb_disscipation public :: atl_init_RANS_closure_coeffs contains subroutine atl_init_RANS_closure_coeffs( equation ) ! -------------------------------------------------------------------------- !> The equation system type(atl_equations_type), intent(inout) :: equation ! -------------------------------------------------------------------------- equation%FiltNavierStokes%rans%turb_prandtl_num = 0.9_rk equation%FiltNavierStokes%rans%sig_k = 0.5_rk equation%FiltNavierStokes%rans%beta_k = 0.09_rk equation%FiltNavierStokes%rans%sig_omg = 0.5_rk equation%FiltNavierStokes%rans%alpha_omg = 5.0/9.0 equation%FiltNavierStokes%rans%beta_omg = 3.0/40.0 equation%FiltNavierStokes%rans%c_mu = 1.0 equation%FiltNavierStokes%rans%alpha = 1.0 end subroutine atl_init_RANS_closure_coeffs ! ******************************************************************************* ! ******************************************************************************* !> Init the variable system for filtered NavierStokes equation. !! !! The variable system describes, which variables are to be used and how !! they are organized in the memory. !! The first few variables up to the sys_mark are those, describing the !! state, and thus describe the output for regular restart files. !! Here these are the conservative variables density, momentum and energy. !! After the mark, there are additional values described that can be deduced !! from the state variables. subroutine atl_init_Rans_vars( equation, solverData ) ! -------------------------------------------------------------------------- !> The equation system type(atl_equations_type), intent(inout) :: equation !> the pointer to the data required for the varsys type(atl_varSys_solverData_type) :: solverData ! -------------------------------------------------------------------------- integer :: nDim = 3 ! -------------------------------------------------------------------------- ! Initialize variable system call tem_varSys_init( me = equation%varSys, & & systemName = 'rans' ) ! Append the required conservative variables for the RANS model call atl_append_rans_consVars(equation, solverData) ! Append primitive variables equation%hasPrimitiveVariables = .true. call atl_append_rans_primVars(equation%varSys, equation%primVar, & & solverData, nDim ) ! Append derived quantities (also sets derive routines for primitive vars) ! @todo : check if all the derived vars are relevent !call append_euler_derivedVars(equation%varSys, solverData) ! for Navier Stokes 3D equation%temp%overSamp = 1 equation%temp%modal = 0 equation%temp%nodal = 3 equation%temp%nScal = equation%varsys%nScalars end subroutine atl_init_Rans_vars ! ******************************************************************************* subroutine atl_init_rans_2d_vars( equation, solverData ) ! -------------------------------------------------------------------------- !> The equation system type(atl_equations_type), intent(inout) :: equation !> the pointer to the data required for the varsys type(atl_varSys_solverData_type) :: solverData ! -------------------------------------------------------------------------- integer :: nDim = 2 ! -------------------------------------------------------------------------- ! Initialize variable system call tem_varSys_init( me = equation%varSys, & & systemName = 'rans_2d' ) ! Append the required conservative variables for the RANS model call atl_append_rans_consVars(equation, solverData) ! Append primitive variables equation%hasPrimitiveVariables = .true. call atl_append_rans_primVars(equation%varSys, equation%primVar, & & solverData, nDim ) ! Append derived quantities (also sets derive routines for primitive vars) call append_rans_2d_derivedVars(equation%varSys, solverData) ! for Rans 2d equation%temp%overSamp = 1 equation%temp%modal = 0 equation%temp%nodal = 3 equation%temp%nScal = equation%varsys%nScalars end subroutine atl_init_rans_2d_vars ! ******************************************************************************* subroutine atl_append_rans_consVars(equation, solverData) ! --------------------------------------------------------------------------- !> The equation type. type(atl_equations_type), intent(inout) :: equation !> the pointer to the data required for the varsys type(atl_varSys_solverData_type), target :: solverData ! --------------------------------------------------------------------------- procedure(tem_varSys_proc_point), pointer :: get_point => null() procedure(tem_varSys_proc_element), pointer :: get_element => null() procedure(tem_varSys_proc_setparams), pointer :: set_params => NULL() procedure(tem_varSys_proc_getparams), pointer :: get_params => NULL() procedure(tem_varSys_proc_setupIndices), pointer :: setup_indices => NULL() procedure(tem_varSys_proc_getValOfIndex), pointer :: get_valOfIndex => NULL() ! --------------------------------------------------------------------------- allocate(equation%stateVar(5)) get_element => atl_varSys_getStateForElement get_point => atl_varSys_getStateForPoint setup_indices => atl_varSys_setupStateIndices get_valOfIndex => atl_varSys_getStateValofIndex ! Append conservative variables to varSys call tem_varSys_append_stateVar( & & me = equation%varSys, & & varName = 'density', & & nComponents = 1, & & method_data = atl_get_new_varSys_data_ptr(solverData), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & pos = equation%stateVar(1) ) call tem_varSys_append_stateVar( & & me = equation%varSys, & & varName = 'momentum', & & nComponents = equation%nDimensions, & & method_data = atl_get_new_varSys_data_ptr(solverData), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & pos = equation%stateVar(2) ) call tem_varSys_append_stateVar( & & me = equation%varSys, & & varName = 'energy', & & nComponents = 1, & & method_data = atl_get_new_varSys_data_ptr(solverData), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & pos = equation%stateVar(3) ) ! Append the Turbulent Kinetic Energy call tem_varSys_append_stateVar( & & me = equation%varSys, & & varName = 'k', & & nComponents = 1, & & method_data = atl_get_new_varSys_data_ptr(solverData), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & pos = equation%stateVar(4) ) ! Append the variable for specific dissipation rate call tem_varSys_append_stateVar( & & me = equation%varSys, & & varName = 'omega', & & nComponents = 1, & & method_data = atl_get_new_varSys_data_ptr(solverData), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & pos = equation%stateVar(5) ) end subroutine atl_append_rans_consVars ! ******************************************************************************* subroutine atl_append_rans_primVars(varSys, primVar, solverData, nDim) ! -------------------------------------------------------------------------- !> The variable system to append primitive variables to type(tem_varSys_type), intent(inout) :: varSys !> Indices of the primitive variables in the overall system. integer, allocatable, intent(out) :: primVar(:) !> the pointer to the data required for the varsys to fulfill all operations !! and derivations on the variables type(atl_varSys_solverData_type), target :: solverData integer, intent(in) :: nDim ! -------------------------------------------------------------------------- logical :: wasAdded procedure(tem_varSys_proc_point), pointer :: get_point => NULL() procedure(tem_varSys_proc_element), pointer :: get_element => NULL() procedure(tem_varSys_proc_setparams), pointer :: set_params => NULL() procedure(tem_varSys_proc_getparams), pointer :: get_params => NULL() procedure(tem_varSys_proc_setupIndices), pointer :: setup_indices => NULL() procedure(tem_varSys_proc_getValOfIndex), pointer :: get_valOfIndex => NULL() type(c_ptr) :: solver_bundle ! -------------------------------------------------------------------------- ! Save var position in primVar allocate(primVar(5)) ! First primitive variable is the density. ! It is already part of the variable system, thus we have to find it. primVar(1) = PositionOfVal(varSys%varname, 'density') ! Second primitive variable is the velocity. ! To compute it, density and momentum of the state are required. get_element => atl_op_divideVecByScal_forElement get_point => tem_divideVecByScal_forPoint setup_indices => tem_opVar_setupIndices get_valOfIndex => tem_divideVecByScal_fromIndex ! get c_ptr from solver method_Data and store it tem_varSys_op_data_type solver_bundle = atl_get_new_varSys_data_ptr(solverData) call tem_varSys_append_derVar( & & me = varSys, & & varName = 'velocity', & & operType = 'divide_vector_by_scalar', & & nComponents = nDim, & & input_varname = ['momentum', 'density '], & & method_data = tem_get_new_varSys_data_ptr(solver_bundle), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & wasAdded = wasAdded, & & pos = primVar(2) ) if (wasAdded) then write(logUnit(10),*) 'Appended variable: velocity' else write(logUnit(1),*) 'Error: variable velocity not appended' call tem_abort() end if ! Third primitive variable is the pressure. ! To compute it all three state variables are required. get_element => atl_Rans_pressure_getElement get_point => atl_Rans_pressure_getPoint setup_indices => atl_opVar_setupIndices call tem_varSys_append_derVar( & & me = varSys, & & varName = 'pressure', & & nComponents = 1, & & input_varname = ['density ', 'momentum', & & 'energy ', 'k '], & & method_data = atl_get_new_varSys_data_ptr(solverData), & & get_point = get_point, & & get_element = get_element, & & set_params = set_params, & & get_params = get_params, & & setup_indices = setup_indices, & & get_valOfIndex = get_valOfIndex, & & pos = primVar(3) ) if (wasAdded) then write(logUnit(10),*) 'Appended variable: Pressure' else write(logUnit(1),*) 'Error: variable Pressure not appended' call tem_abort() end if ! Fourth primitive variable is the turbulent KE. ! It is already part of the variable system, thus we have to find it. primVar(4) = PositionOfVal(varSys%varname, 'k') ! Fifth primitive variable is the specific dissipation rate. ! It is already part of the variable system, thus we have to find it. primVar(5) = PositionOfVal(varSys%varname, 'omega') get_element => null() get_point => null() set_params => null() get_params => null() setup_Indices => null() get_valOfindex => null() end subroutine atl_append_rans_primVars ! ******************************************************************************* subroutine append_rans_2d_derivedVars( varSys, solverData ) ! ------------------------------------------------------------------------ type(tem_varSys_type), intent(inout) :: varSys !> the pointer to the data required for the varsys to fulfill all operations !! and derivations on the variables type(atl_varSys_solverData_type), target :: solverData ! ------------------------------------------------------------------------ ! integer :: nDerivedVars, iVar, nComponents ! character(len=20), allocatable :: derVarName(:) ! character(len=labelLen), allocatable :: invar_name(:) ! character(len=labelLen) :: varname ! logical :: wasAdded procedure(tem_varSys_proc_point), pointer :: get_point => NULL() procedure(tem_varSys_proc_element), pointer :: get_element => NULL() procedure(tem_varSys_proc_setparams), pointer :: set_params => NULL() procedure(tem_varSys_proc_getparams), pointer :: get_params => NULL() procedure(tem_varSys_proc_setupIndices), pointer :: setup_indices => NULL() procedure(tem_varSys_proc_getValOfIndex), pointer :: get_valOfIndex => NULL() ! ------------------------------------------------------------------------ ! wasAdded = .False. ! ! !@todo Write derive routines for the primitive variables ! nDerivedVars = 1 ! allocate(derVarName(nDerivedVars)) ! ! ! derVarName = [ 'track_source '] ! ! do iVar = 1, nDerivedVars ! varname = trim(adjustl(derVarName(iVar))) ! select case(varname) !! !! ! Define the speed of sound as new possible variable to derive. ! case ('track_source') ! get_point => Null() ! get_element => Null() ! nComponents = 6 ! allocate(invar_name(5)) ! invar_name(1) = 'density' ! invar_name(2) = 'momentum' ! invar_name(3) = 'energy' ! invar_name(4) = 'k' ! invar_name(5) = 'omega' ! ! case default ! write(logUnit(1),*) 'WARNING: Unknown variable: '//trim(varname) ! cycle !go to next variable ! ! end select ! ! ! append variable to varSys ! call tem_varSys_append_derVar( & ! & me = varSys, & ! & varName = varname, & ! & nComponents = nComponents, & ! & input_varname = invar_name, & ! & method_data = atl_get_new_varSys_data_ptr(methoddata), & ! & get_point = get_point, & ! & get_element = get_element, & ! & wasAdded = wasAdded ) ! ! call outputAppendResult( wasAdded, varname ) ! ! deallocate(invar_name) ! ! end do ! ! deallocate(derVarName) end subroutine append_rans_2d_derivedVars ! ******************************************************************************* !> Init source terms for flow simulations. !> This routine initializes possible source variables and returns the filled !! up list of the poss_srcVars subroutine atl_init_filNvrStk_sourceTerms(possVars, eval_source, model_type) ! -------------------------------------------------------------------------- type(tem_possible_variable_type), intent(inout) :: possVars type(atl_eqn_sourceMap_type), allocatable, intent(out) :: eval_source(:) character(len=32), intent(in) :: model_type ! -------------------------------------------------------------------------- integer :: pos ! -------------------------------------------------------------------------- allocate(eval_source(1)) call init(me = possVars%varName, length = 1) select case (trim(model_type)) case('rans') !NA! ! Add the arbitrary Source term !NA! call append( me = possVars, & !NA! & varName = 'ransSource', & !NA! & nComponents = 7, & !NA! & pos = pos ) !NA! eval_source(pos)%do => eval_source_rans case('rans_2d') ! Add the source term in the call append( me = possVars, & & varName = 'rans2dsource', & & nComponents = 6, & & pos = pos ) eval_source(pos)%do => eval_source_rans2D end select call truncate(possVars%varName) call truncate(possVars%nComponents) end subroutine atl_init_filNvrStk_sourceTerms subroutine eval_source_rans2D( fun, varSys, time, mesh, poly_proj, & & currentLevel, state, material, sourcedata ) ! --------------------------------------------------------------------------- !> Description of method to update source class(atl_source_op_type), intent(in) :: fun !> variable system type(tem_varSys_type), intent(in) :: varSys !> Point in time at which to evaluate the variable. type(tem_time_type), intent(in) :: time !> Current level mesh information type(atl_cube_elem_type), intent(in) :: mesh !> Parameters for projection type(ply_poly_project_type), intent(inout) :: poly_proj !> current level integer, intent(in) :: currentLevel !> The state in modal space. !! This is needed for several source terms that have to be applied to the !! current state real(kind=rk), intent(in) :: state(:,:,:) !> Material description for the background on the current level real(kind=rk), intent(in) :: material(:) !> The source data to update. When all source terms are added to this !! buffer, it is applied to the state. real(kind=rk), intent(inout) :: sourcedata(:,:,:) ! --------------------------------------------------------------------------- !procedure(compute_source_interface) , pointer:: evaluate_source ! The modal coefficients of the current element in the loop. real(kind=rk), allocatable :: modalCoeffs(:,:), modal_grad(:,:,:) ! Nodal representation of the polynomial with in each cell. real(kind=rk), allocatable :: pointVal(:,:), pointVal_grad(:,:,:) real(kind=rk), allocatable :: rhsNodal(:,:), rhsModal(:,:), rhs(:,:) real(kind=rk) :: rey_stress_tensor(2,2) integer :: iElem, iDir integer :: iPoint real(kind=rk) :: beta_k, omega_r, alp_omg, beta_omg, sig_omg real(kind=rk) :: mu_turb, mu, c_mu, alpha, source(2), omega, k_bar real(kind=rk) :: velGrad(2,2), ViscStressTensor(2,2) type(atl_varSys_data_type), pointer :: fPtr type(atl_equations_type), pointer :: eqn real(kind=rk) :: d_omega1, d_omega2 ! --------------------------------------------------------------------------- call C_F_POINTER( varSys%method%val(fun%srcTerm_varPos)%method_Data, fPtr ) eqn => fPtr%solverData%equationPtr beta_k = eqn%FiltNavierStokes%rans%beta_k beta_omg = eqn%FiltNavierStokes%rans%beta_omg alp_omg = eqn%FiltNavierStokes%rans%alpha_omg c_mu = eqn%FiltNavierStokes%rans%c_mu alpha = eqn%FiltNavierStokes%rans%alpha mu = eqn%NavierStokes%mu sig_omg = eqn%FiltNavierStokes%rans%sig_omg allocate( modalCoeffs (poly_proj%Body_2D%OverSamp_dofs ,varSys%nScalars )) allocate( modal_grad (poly_proj%Body_2D%OverSamp_dofs,varSys%nScalars,2 )) allocate( pointVal (poly_proj%Body_2D%nQuadPoints,varSys%nScalars ) ) allocate( pointVal_grad (poly_proj%Body_2D%nQuadPoints,varSys%nScalars,2 )) allocate( rhsNodal (poly_proj%Body_2D%nQuadPoints, varSys%nScalars ) ) allocate( rhsModal (poly_proj%Body_2D%OverSamp_dofs, varSys%nScalars ) ) allocate( rhs (poly_proj%body_2d%nDofs, varSys%nScalars )) rhsNodal = 0.0_rk do iElem = 1, fun%elems(currentLevel)%nElems ! --> modal space call ply_convert2oversample(state = state(iElem,:,:), & & poly_proj = poly_proj, & & nDim = 2, & & modalCoeffs = modalCoeffs ) ! --> oversamp modal space ! Calculate the gradient of modal Coeffs call ply_calcDiff_leg_2d( legCoeffs = modalCoeffs, & & legCoeffsDiff = modal_grad, & & maxPolyDegree = poly_proj%oversamp_degree, & & nVars = varsys%nScalars, & & elemLength = mesh%length ) ! Now, we transform the modal representation of this element to nodal ! space by making use of fast polynomial transformations (FPT) call ply_poly_project_m2n(me = poly_proj, & & dim = 2 , & & nVars = varSys%nScalars, & & nodal_data= pointVal, & & modal_data= modalCoeffs ) ! --> oversamp nodal space ! Now, transform modal gradient representation of this element to ! nodal space by making use of fast polynomial transformations (FPT) do iDir = 1, 2 call ply_poly_project_m2n(me = poly_proj, & & dim = 2, & & nVars = varSys%nScalars, & & nodal_data = pointVal_grad(:,:,iDir), & & modal_data = modal_grad(:,:,iDir) ) end do do iPoint = 1, poly_proj%Body_2D%nQuadPoints call atl_get_pointwise_velocity_gradient_2D( & & pointVal_grad(iPoint,:,:), & & pointVal(iPoint,:), & & velGrad ) call atl_get_pointwise_visc_stress_tensor_2D( & & velGrad = velGrad, & & S = ViscStressTensor ) ! get the value of \omega_r call atl_get_lower_bound_turb_disscipation( & & S = ViscStressTensor, & & c_mu = c_mu, & & omega = pointVal(iPoint, 6 )/ pointVal(iPoint,1), & & omega_r = omega_r ) ! Calculate the limited turbulent eddy viscosity mu_turb = alpha * max(pointVal(iPoint,5),0.0)* exp(-omega_r) !Careful - This routine returns the reynolds tensor divided by ! the limited "k" (\bar{k}) call get_rans_reynolds_tensor_2D( & & state = pointVal(iPoint,:), & & alpha = alpha, & & omega_r = omega_r, & & velGrad = velGrad, & & rey_stress_tensor = rey_stress_tensor ) omega = exp( pointVal(iPoint,6)/ pointVal(iPoint,1) ) k_bar = max(pointVal(iPoint,5)/pointVal(iPoint,1),0.0) d_omega1 = (pointVal_grad(iPoint,6,1) - pointVal(iPoint,6) & & *pointval_grad(iPoint,1,1)/pointVal(iPoint,1) ) & & *pointVal(iPoint,1) d_omega2 = (pointVal_grad(iPoint,6,2) - pointVal(iPoint,6) & & *pointval_grad(iPoint,1,2)/pointVal(iPoint,1) ) & & / pointVal(iPoint,1) ! Note: The first four comonents of the source term = 0 ! This is the source corresponding to the fifth var i.e turbulent KE ! the multiplication with k_bar as the rey_stress_tensor used here is ! divided by k_bar source(1) = rey_stress_tensor(1,1)*velGrad(1,1)*k_bar & & + rey_stress_tensor(1,2)*velGrad(1,2)*k_bar & & + rey_stress_tensor(2,1)*velGrad(2,1)*k_bar & & + rey_stress_tensor(2,2)*velGrad(2,2)*k_bar & & - beta_k*max(pointVal(iPoint,5),0.0)& *exp(omega_r) ! This is the source corresponding to the sixth conservative var ! i.e specific dissipation rate source(2) = ( & & rey_stress_tensor(1,1)*velGrad(1,1) & & + rey_stress_tensor(1,2)*velGrad(1,2) & & + rey_stress_tensor(2,1)*velGrad(2,1) & & + rey_stress_tensor(2,2)*velGrad(2,2) ) & & *alp_omg*omega & & - beta_omg*pointVal(iPoint,1)*exp(omega_r) & & + (mu + sig_omg*mu_turb) & & * ( d_omega1*d_omega1 & & + d_omega2*d_omega2 ) !write(*,*) "**>", iPoint, source, pointVal(iPoint,:) ! Debug statement rhsNodal(iPoint,5:6) = rhsNodal(iPoint,5:6) + source(1:2) end do ! Convert everything back to modal space call ply_poly_project_n2m( me = poly_proj, & & dim = 2, & & nVars = varSys%nScalars, & & nodal_data = rhsNodal(:,:), & & modal_data = rhsModal(:,:) ) ! --> oversamp modal space call ply_convertFromoversample( modalCoeffs = rhsModal(:,:), & & poly_proj = poly_proj, & & nDim = 2, & & state = rhs(:,:) ) ! --> oversampled modal space ! Add rhsmodal to the source representation sourcedata(iElem,:,:) = sourcedata(iElem,:,:) + rhs(:,:) end do ! Elems Loop deallocate( modalCoeffs ) deallocate( modal_grad ) deallocate( pointVal ) deallocate( pointVal_grad ) deallocate( rhsNodal ) deallocate( rhsModal ) deallocate( rhs ) end subroutine eval_source_rans2D ! ******************************************************************************* ! Calculates the velocity gradient from the available state gradient subroutine atl_get_pointwise_velocity_gradient_2D( state_grad, state, res ) ! --------------------------------------------------------------------------- real(kind=rk), intent(in) :: state_grad(:,:) ! The gradient of the state real(kind=rk), intent(in) :: state(:) ! Reynolds_stress_tensor real(kind=rk), intent(inout) :: res(:,:) ! --------------------------------------------------------------------------- real(kind=rk) :: dens_sq ! --------------------------------------------------------------------------- dens_sq = state(1)*state(1) ! fill up the four velocity gradients. res(1,1) = state_grad(2,1)/ state(1) - state(2) * state_grad(1,1)/ dens_sq res(2,1) = state_grad(3,1)/ state(1) - state(3) * state_grad(1,1)/ dens_sq res(1,2) = state_grad(2,2)/ state(1) - state(2) * state_grad(1,2)/ dens_sq res(2,2) = state_grad(3,2)/ state(1) - state(3) * state_grad(1,2)/ dens_sq end subroutine atl_get_pointwise_velocity_gradient_2D ! ******************************************************************************* ! Takes the pointwise velocity gradient as the input and evaluates ! the four components of viscous stress tensor subroutine atl_get_pointwise_visc_stress_tensor_2D( velGrad, S ) ! --------------------------------------------------------------------------- ! The gradient of the state real(kind=rk), intent(in) :: velGrad(2,2) ! Viscous stress tensor - the output real(kind=rk), intent(inout) :: S(2,2) ! --------------------------------------------------------------------------- S(1,1) = 4.0* velGrad(1,1)/ 3.0 - 2.0* velGrad(2,2)/ 3.0 S(1,2) = velGrad(1,2) + velGrad(2,1) S(2,1) = S(1,2) S(2,2) = 4.0 * velGrad(2,2)/ 3.0 - 2.0* velGrad(1,1)/ 3.0 end subroutine atl_get_pointwise_visc_stress_tensor_2D ! ******************************************************************************* ! takes pointwise input and evaluates the lower bound of the turbulent ! dissipation to ensure the positivity of normal turbulent stresses. ! The fulfilement of the inequality solved in this routine is the same as ! one proposed by Wilcox for the k-\omega turbulence model and also used ! in the Hartmann paper. Here we just solve this quadratic inequality subroutine atl_get_lower_bound_turb_disscipation( S, c_mu, omega, Omega_r ) ! Viscous stress tensor real(kind=rk), intent(in) :: S(2,2) ! The constant c_mu real(kind=rk), intent(in) :: c_mu ! The state omega real(kind=rk), intent(in) :: omega ! The lower bound on omega real(kind=rk), intent(out) :: omega_r ! --------------------------------------------------------------------------- ! The constants needed real(kind=rk) :: C3,C4 ! The omegas real(kind=rk) :: omega_r0 real(kind=rk) :: omg1, omg2, omg3 ! --------------------------------------------------------------------------- if (S(1,1) > 0.0_rk) then omg1 = 3.0 *c_mu * (S(1,1) ) / 2.0 else omg1 = 0.0_rk end if if (S(2,2) > 0.0_rk) then omg2 = 3.0 *c_mu * (S(2,2) ) / 2.0 else omg2 = 0.0_rk end if C3 = - 3.0 *c_mu * ( S(1,1) + S(2,2))/2.0 C4 = 9.0 *c_mu * c_mu * (S(1,1)* S(2,2) - S(1,2)*S(1,2))/ 4.0 if ( (C3 * C3 - 4.0*C4) > 0 ) then omg3 = - (C3 + sqrt( C3 * C3 - 4.0*C4) )/ 2.0 else omg3 = 0.0_rk end if omega_r0 = max(omg1, omg2, omg3, tiny(omega)) omega_r0 = log(omega_r0) omega_r = max(omega, omega_r0) end subroutine atl_get_lower_bound_turb_disscipation ! ******************************************************************************* ! This routine calculates the reynolds tensor and returns the result divided ! by \bar{k} = \frac{\bar{\mu_t}}{\alpha \rho e^{\tilde{\omega_r}}} subroutine get_rans_reynolds_tensor_2D( state, alpha, omega_r, velGrad, & & rey_stress_tensor ) ! --------------------------------------------------------------------------- !! current state real(kind=rk), intent(in) :: state(:) ! \alpha for the evaluation of limited \mu_t (turbulent eddy viscosity) real(kind=rk), intent(in) :: alpha ! lower bound of \omega = \omega_r for the evaluation of limited ! \mu_t (turbulent eddy viscosity) real(kind=rk), intent(in) :: omega_r ! The velocity gradient real(kind=rk), intent(in) :: velGrad(2,2) ! Reynolds_stress_tensor real(kind=rk), intent(inout) :: rey_stress_tensor(:,:) ! --------------------------------------------------------------------------- real(kind=rk) :: fact ! --------------------------------------------------------------------------- fact = alpha*state(1)*exp(-omega_r) rey_stress_tensor(1,1) = (4.0*velGrad(1,1) - 2.0*velGrad(2,2) ) & & *fact / 3.0 - 2.0 * state(1) / 3.0 rey_stress_tensor(1,2) = fact*(velGrad(1,2) + velGrad(2,1)) rey_stress_tensor(2,1) = rey_stress_tensor(1,2) rey_stress_tensor(2,2) = fact*( 4.0*velGrad(2,2) - 2.0*velGrad(1,1)) / 3.0 & & - 2.0 * state(1) / 3.0 end subroutine get_rans_reynolds_tensor_2D ! ******************************************************************************* end module atl_eqn_filNvrStk_var_module