Path: blob/devel/elmerice/UserFunctions/USF_GetFrictionHeating.F90
3196 views
!/*****************************************************************************/1! *2! * Elmer, A Finite Element Software for Multiphysical Problems3! *4! * Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland5! *6! * This program is free software; you can redistribute it and/or7! * modify it under the terms of the GNU General Public License8! * as published by the Free Software Foundation; either version 29! * of the License, or (at your option) any later version.10! *11! * This program is distributed in the hope that it will be useful,12! * but WITHOUT ANY WARRANTY; without even the implied warranty of13! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14! * GNU General Public License for more details.15! *16! * You should have received a copy of the GNU General Public License17! * along with this program (in file fem/GPL-2); if not, write to the18! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,19! * Boston, MA 02110-1301, USA.20! *21! *****************************************************************************/22!23!/******************************************************************************24! *25! * Module containing a functions for friction heat26! *27! ******************************************************************************28! *29! * Authors: Thomas Zwinger, Juha Ruokolainen, Joe Todd30! * Email: [email protected]31! * Web: http://www.csc.fi/elmer32! * Address: CSC - IT Center for Science Ltd.33! * Keilaranta 1434! * 02101 Espoo, Finland35! *36! * Original Date: 08 Jun 199737! * Current date: 20 July 2012 (Martina)38! *39! *****************************************************************************/404142! contains function for adding friction heat to geothermal heat flux at the basis and exporting it43! ATTENTION: consistent units for capacity and conductivy are needed.44! ATTENTION: The keyword "Friction Heat" does make reference to Strainheating, not Friction heat!45! usage:4647484950FUNCTION getFrictionHeat( Model, Node, DummyInput)RESULT(frictionheat)5152USE DefUtils5354IMPLICIT NONE5556!------------------------------------------------------------------------------57TYPE(Model_t) :: Model58INTEGER :: Node59REAL(KIND=dp) :: DummyInput, frictionHeat60!----------------------------------------------------------------------------6162INTEGER :: DIM, i, j, Ind(3,3)63REAL(KIND=dp), POINTER :: FlowValues(:),NormalValues(:),StressValues(:)64REAL(KIND=dp) :: normal(3), velo(3), un, ut, Sig(3,3), Sn(3), snn, snt65INTEGER, POINTER :: FlowPerm(:),StressPerm(:), NormalPerm(:)66LOGICAL :: FirstTime=.TRUE.,UnFoundFatal=.TRUE.67TYPE(Variable_t), POINTER :: FlowVar,StressVariable, NormalVar68CHARACTER(LEN=MAX_NAME_LEN) :: FunctionName6970SAVE FirstTime, DIM, FunctionName,Ind7172IF (FirstTime) THEN73WRITE(FunctionName, '(A)') 'getFrictionHeat'74DIM = CoordinateSystemDimension()75FirstTime = .FALSE.76DO i=1, 377Ind(i,i) = i78END DO79Ind(1,2) = 480Ind(2,1) = 481Ind(2,3) = 582Ind(3,2) = 583Ind(3,1) = 684Ind(1,3) = 685END IF8687! Get the variable velocity88!---------------------------89FlowVar => VariableGet( Model % Variables, 'Flow Solution',UnFoundFatal=UnFoundFatal)90FlowPerm => FlowVar % Perm91FlowValues => FlowVar % Values9293! Get the stress variable94!------------------------95StressVariable => VariableGet( Model % Variables, 'Stress',UnFoundFatal=UnFoundFatal)96StressPerm => StressVariable % Perm97StressValues => StressVariable % Values9899! Get the variable for normal vector100NormalVar => VariableGet(Model % Variables,'Normal Vector',UnFoundFatal=UnFoundFatal)101NormalPerm => NormalVar % Perm102NormalValues => NormalVar % Values103104DO i=1, DIM105normal(i) = NormalValues(DIM*(NormalPerm(Node)-1) + i)106velo(i) = FlowValues( (DIM+1)*(FlowPerm(Node)-1) + i )107END DO108109!Tangential velocity110un = SUM(velo(1:DIM)*(normal(1:DIM)))111ut = SQRT(SUM( (velo(1:DIM))**2.0_dp ) - (un**2.0_dp) )112113!Tangential Stress114DO i=1, DIM115DO j= 1, DIM116Sig(i,j) = &117StressValues( 2*DIM *(StressPerm(Node)-1) + Ind(i,j) )118END DO119END DO120DO i=1, DIM121Sn(i) = SUM(Sig(i,1:DIM)*normal(1:DIM))122END DO123Snn = SUM( Sn(1:DIM) * normal(1:DIM) )124Snt = SQRT( SUM(Sn(1:DIM)**2.0_dp) - (Snn**2.0_dp))125126frictionHeat =ut*Snt127END FUNCTION getFrictionHeat128129!/******************************************************************************130! *131! * Module containing a functions for friction heat based132! * on residuals from (Navier-)Stokes solver133! * This function should be preferably used to compute the heat production134! * at the base, as it utilizes the natural way to couple the flow135! * and temperature solution136! *137! ******************************************************************************138! *139! * Authors: Thomas Zwinger, Juha Ruokolainen, Martina Schäfer, Olivier Gagliardini140! * Email: [email protected]141! * Web: http://www.csc.fi/elmer142! * Address: CSC - IT Center for Science Ltd.143! * Keilaranta 14144! * 02101 Espoo, Finland145! *146! * Original Date: 08 Jun 1997147! * Current date: 28 August 2014 (Martina/Thomas)148! *149! *****************************************************************************/150151FUNCTION getFrictionLoads( Model, Node, DummyInput )RESULT(frictionLoad)152153USE DefUtils154155IMPLICIT NONE156157!------------------------------------------------------------------------------158TYPE(Model_t) :: Model159INTEGER :: Node160REAL(KIND=dp) :: DummyInput, frictionLoad161!----------------------------------------------------------------------------162163INTEGER :: DIM, i, other_body_id164REAL(KIND=dp), POINTER :: FlowValues(:),FlowLoadValues(:),NormalValues(:),MaskValues(:)165REAL(KIND=dp) :: normal(3), velo(3), normalvelocity, flowload(3), tangvelocity(3)166INTEGER, POINTER :: FlowPerm(:),FlowLoadPerm(:), NormalPerm(:), MaskPerm(:)167LOGICAL :: FirstTime=.TRUE., GotIt,UnFoundFatal,UseMask = .FALSE., Warned=.FALSE.168TYPE(Variable_t), POINTER :: FlowVar,FlowLoadVar, NormalVar, MaskVar169TYPE(ValueList_t), POINTER :: Equation170CHARACTER(LEN=MAX_NAME_LEN) :: FlowSolutionName, FlowLoadsName, MaskName171CHARACTER(LEN=MAX_NAME_LEN), PARAMETER :: FunctionName='USF_GetFrictionHeating(getFrictionLoads)'172TYPE(Element_t), POINTER :: BoundaryElement, ParentElement173174SAVE FirstTime, DIM, UseMask175176177IF (FirstTime) THEN178!WRITE(FunctionName,'(A)') 'USF_GetFrictionHeating(getFrictionLoads)'179180DIM = CoordinateSystemDimension()181END IF182183! Get variable names from Equation section184!-----------------------------------------185BoundaryElement => Model % CurrentElement186other_body_id = BoundaryElement % BoundaryInfo % outbody187IF (other_body_id < 1) THEN ! only one body in calculation188ParentElement => BoundaryElement % BoundaryInfo % Right189IF ( .NOT. ASSOCIATED(ParentElement) ) ParentElement => BoundaryElement % BoundaryInfo % Left190ELSE ! we are dealing with a body-body boundary and assume that the normal is pointing outwards191ParentElement => BoundaryElement % BoundaryInfo % Right192IF (ParentElement % BodyId == other_body_id) ParentElement => BoundaryElement % BoundaryInfo % Left193END IF194Equation => GetEquation(Element=ParentElement,Found=GotIt)195IF (.NOT.ASSOCIATED(Equation) .OR. .NOT.GotIt) THEN196IF (FirstTime) THEN197WRITE (Message,'(A,I3)') 'No "Equation" found. Using default values for variables'198CALL WARN(FunctionName,Message)199Warned = .TRUE.200END IF201WRITE(FlowSolutionName,'(A)') 'Flow Solution'202WRITE(FlowLoadsName,'(A)') TRIM(FlowSolutionName)//' Loads'203UseMask = .FALSE.204ELSE205FlowSolutionName = GetString( Equation , 'Flow Solution Name', GotIt )206IF (.NOT.GotIt) THEN207WRITE(FlowSolutionName,'(A)') 'Flow Solution'208IF (FirstTime) THEN209WRITE(Message,'(A,A)') 'Using default name for flow solution: ', &210FlowSolutionName211CALL WARN(FunctionName,Message)212Warned = .TRUE.213END IF214END IF215FlowLoadsName = GetString( Equation , 'Flow Loads Name', GotIt )216IF (.NOT. GotIt) THEN217WRITE(FlowLoadsName,'(A)') TRIM(FlowSolutionName)//' Loads'218IF (FirstTime) THEN219WRITE(Message,'(A,A)') 'Using default name for flow solution loads: ', &220FlowLoadsName221CALL WARN(FunctionName,Message)222Warned = .TRUE.223END IF224END IF225MaskName = GetString( Equation , 'Friction Load Mask', UseMask )226IF (UseMask) THEN227WRITE (Message, '(A,A)') '>Friction Load Mask< found and set to ', &228TRIM(MaskName)229CALL INFO(FunctionName, Message, Level=20)230END IF231END IF232IF (Warned .AND. FirstTime) &233CALL WARN(FunctionName,"All Warnings will be further omitted")234FirstTime = .FALSE.235236! Get the variable velocity237!---------------------------238FlowVar => VariableGet( Model % Variables, TRIM(FlowSolutionName),UnFoundFatal=UnFoundFatal)239FlowPerm => FlowVar % Perm240FlowValues => FlowVar % Values241242243! Get the Stokes loads244!---------------------------245FlowLoadVar => VariableGet( Model % Variables, TRIM(FlowLoadsName),UnFoundFatal=UnFoundFatal)246FlowLoadPerm => FlowLoadVar % Perm247FlowLoadValues => FlowLoadVar % Values248249250! Get the variable for normal vector251!-----------------------------------252NormalVar => VariableGet(Model % Variables,'Normal Vector',UnFoundFatal=UnFoundFatal)253NormalPerm => NormalVar % Perm254NormalValues => NormalVar % Values255256IF (UseMask) THEN257MaskVar => VariableGet( Model % Variables, TRIM(MaskName),UnFoundFatal=UnFoundFatal)258MaskPerm => MaskVar % Perm259MaskValues => MaskVar % Values260END IF261262IF (UseMask) THEN263IF ( MaskValues(MaskPerm(Node)).LE.0.0_dp ) THEN264frictionLoad = 0.0_dp265END IF266ELSE267DO i=1, DIM268normal(i) = NormalValues(DIM*(NormalPerm(Node)-1) + i)269velo(i) = FlowValues( (DIM+1)*(FlowPerm(Node)-1) + i )270flowload(i) = FlowLoadValues( (DIM+1)*(FlowLoadPerm(Node)-1) + i )271END DO272273normalvelocity = SUM( velo(1:DIM) * normal(1:DIM) )274275DO i=1, DIM276tangvelocity(i) = velo(i) - normalvelocity * normal(i)277END DO278279frictionLoad = &280MAX( (-1.0_dp * (SUM(tangvelocity(1:DIM) * flowLoad(1:DIM)))), 0.0_dp)281END IF282283END FUNCTION getFrictionLoads284285286