Path: blob/devel/elmerice/IceSheet/Tools/ConservativeInterpolation/CELL_TO_NODE.F90
3206 views
!/*****************************************************************************/1! *2! * Elmer/Ice, a glaciological add-on to Elmer3! * http://elmerice.elmerfem.org4! *5! *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! * Authors: F. Gillet-Chaulet (IGE-France)25! * Web: http://elmerice.elmerfem.org26! * Original Date: 04/201927! *28! *****************************************************************************29!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!30! Conservative FE projection of element variable to a nodal variable31! Required Solver parameters:32! Elemental Variable Name = String33! Nodal Variable Name = String34!35!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!36SUBROUTINE CELL_TO_NODE( Model,Solver,dt,TransientSimulation )37!------------------------------------------------------------------------------38USE DefUtils39IMPLICIT NONE40!------------------------------------------------------------------------------41TYPE(Solver_t), TARGET :: Solver42TYPE(Model_t) :: Model43REAL(KIND=dp) :: dt44LOGICAL :: TransientSimulation45!------------------------------------------------------------------------------46! Local variables47CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="CELL_TO_NODE"48TYPE(ValueList_t), POINTER :: SolverParams49TYPE(Variable_t),POINTER :: EVar,NVar50TYPE(Element_t), POINTER :: Element51TYPE(Nodes_t),SAVE :: ElementNodes52TYPE(GaussIntegrationPoints_t) :: IntegStuff53REAL(KIND=dp),allocatable,SAVE :: weight(:),NodalVar(:)54REAL(KIND=dp),allocatable,SAVE :: Basis(:), dBasisdx(:,:)55REAL(KIND=dp) :: U,V,W,SqrtElementMetric56INTEGER, POINTER :: NodeIndexes(:)57INTEGER, POINTER :: Perm(:)58INTEGER :: i,t59INTEGER :: ne,n60INTEGER :: EIndex61CHARACTER (len=100) :: EVarName,NVarName62LOGICAL :: Parallel63LOGICAL, SAVE :: FirstTime=.TRUE.64LOGICAL :: stat6566IF (.NOT.ASSOCIATED(Solver % Variable)) &67CALL FATAL(SolverName,'Solver should have a variable associated')68Perm => Solver % Variable % Perm6970IF (FirstTime) THEN71ALLOCATE( weight( Model % NumberOfNodes ),&72NodalVar ( Model % NumberOfNodes ),&73Basis(Model % MaxElementNodes),&74dBasisdx(Model % MaxElementNodes,3))75FirstTime=.FALSE.76END IF7778! get parameters79SolverParams => GetSolverParams()8081EVarName = ListGetString(SolverParams,'Elemental Variable Name',UnFoundFatal=.TRUE.)82NVarName = ListGetString(SolverParams,'Nodal Variable Name',UnFoundFatal=.TRUE.)8384! check if this is a parallel run85Parallel=(ParEnv % PEs > 1)8687! get variables88EVar => VariableGet( Model % Mesh % Variables,TRIM(EVarName),UnFoundFatal=.TRUE.)89IF(EVar % TYPE /= Variable_on_elements) &90CALL FATAL(SolverName,'Wrong variable type; use -elem ')9192NVar => VariableGet( Model % Mesh % Variables,TRIM(NVarName),UnFoundFatal=.TRUE.)93IF(NVar % TYPE /= Variable_on_nodes) &94CALL FATAL(SolverName,'Wrong variable type; should be nodal')9596NodalVar=0._dp97weight=0._dp9899ne=GetNOFActive()100DO t = 1,ne101Element => GetActiveElement(t)102EIndex = Element % ElementIndex103104NodeIndexes => Element % NodeIndexes105IF ( ANY(Perm(NodeIndexes) == 0) ) CYCLE106107n = GetElementNOFNodes()108CALL GetElementNodes( ElementNodes )109110IntegStuff = GaussPoints( Element )111112DO i=1,IntegStuff % n113U = IntegStuff % u(i)114V = IntegStuff % v(i)115W = IntegStuff % w(i)116117stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &118Basis,dBasisdx )119120NodalVar(Perm(NodeIndexes(1:n)))=&121NodalVar(Perm(NodeIndexes(1:n)))+ &122EVAR % Values(EVar % Perm(EIndex))*SqrtElementMetric*IntegStuff % s(i) * Basis(1:n)123124weight(Perm(NodeIndexes(1:n)))=weight(Perm(NodeIndexes(1:n)))+&125SqrtElementMetric*IntegStuff % s(i) * Basis(1:n)126END DO127END DO128129IF (Parallel) THEN130CALL ParallelSumVector(Solver % Matrix, NodalVar)131CALL ParallelSumVector(Solver % Matrix, weight)132END IF133134DO i = 1, Model % NumberOfNodes135IF ( ABS( weight(Perm(i)) ) > 0.0D0 ) THEN136NVar % Values (NVar % Perm(i)) = NodalVar(Perm(i)) / weight(Perm(i))137END IF138END DO139140141END SUBROUTINE CELL_TO_NODE142143144