Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/IceSheet/Tools/ConservativeInterpolation/CELL_TO_NODE.F90
3206 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer/Ice, a glaciological add-on to Elmer
4
! * http://elmerice.elmerfem.org
5
! *
6
! *
7
! * This program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
! ******************************************************************************
24
! *
25
! * Authors: F. Gillet-Chaulet (IGE-France)
26
! * Web: http://elmerice.elmerfem.org
27
! * Original Date: 04/2019
28
! *
29
! *****************************************************************************
30
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
31
! Conservative FE projection of element variable to a nodal variable
32
! Required Solver parameters:
33
! Elemental Variable Name = String
34
! Nodal Variable Name = String
35
!
36
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
37
SUBROUTINE CELL_TO_NODE( Model,Solver,dt,TransientSimulation )
38
!------------------------------------------------------------------------------
39
USE DefUtils
40
IMPLICIT NONE
41
!------------------------------------------------------------------------------
42
TYPE(Solver_t), TARGET :: Solver
43
TYPE(Model_t) :: Model
44
REAL(KIND=dp) :: dt
45
LOGICAL :: TransientSimulation
46
!------------------------------------------------------------------------------
47
! Local variables
48
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="CELL_TO_NODE"
49
TYPE(ValueList_t), POINTER :: SolverParams
50
TYPE(Variable_t),POINTER :: EVar,NVar
51
TYPE(Element_t), POINTER :: Element
52
TYPE(Nodes_t),SAVE :: ElementNodes
53
TYPE(GaussIntegrationPoints_t) :: IntegStuff
54
REAL(KIND=dp),allocatable,SAVE :: weight(:),NodalVar(:)
55
REAL(KIND=dp),allocatable,SAVE :: Basis(:), dBasisdx(:,:)
56
REAL(KIND=dp) :: U,V,W,SqrtElementMetric
57
INTEGER, POINTER :: NodeIndexes(:)
58
INTEGER, POINTER :: Perm(:)
59
INTEGER :: i,t
60
INTEGER :: ne,n
61
INTEGER :: EIndex
62
CHARACTER (len=100) :: EVarName,NVarName
63
LOGICAL :: Parallel
64
LOGICAL, SAVE :: FirstTime=.TRUE.
65
LOGICAL :: stat
66
67
IF (.NOT.ASSOCIATED(Solver % Variable)) &
68
CALL FATAL(SolverName,'Solver should have a variable associated')
69
Perm => Solver % Variable % Perm
70
71
IF (FirstTime) THEN
72
ALLOCATE( weight( Model % NumberOfNodes ),&
73
NodalVar ( Model % NumberOfNodes ),&
74
Basis(Model % MaxElementNodes),&
75
dBasisdx(Model % MaxElementNodes,3))
76
FirstTime=.FALSE.
77
END IF
78
79
! get parameters
80
SolverParams => GetSolverParams()
81
82
EVarName = ListGetString(SolverParams,'Elemental Variable Name',UnFoundFatal=.TRUE.)
83
NVarName = ListGetString(SolverParams,'Nodal Variable Name',UnFoundFatal=.TRUE.)
84
85
! check if this is a parallel run
86
Parallel=(ParEnv % PEs > 1)
87
88
! get variables
89
EVar => VariableGet( Model % Mesh % Variables,TRIM(EVarName),UnFoundFatal=.TRUE.)
90
IF(EVar % TYPE /= Variable_on_elements) &
91
CALL FATAL(SolverName,'Wrong variable type; use -elem ')
92
93
NVar => VariableGet( Model % Mesh % Variables,TRIM(NVarName),UnFoundFatal=.TRUE.)
94
IF(NVar % TYPE /= Variable_on_nodes) &
95
CALL FATAL(SolverName,'Wrong variable type; should be nodal')
96
97
NodalVar=0._dp
98
weight=0._dp
99
100
ne=GetNOFActive()
101
DO t = 1,ne
102
Element => GetActiveElement(t)
103
EIndex = Element % ElementIndex
104
105
NodeIndexes => Element % NodeIndexes
106
IF ( ANY(Perm(NodeIndexes) == 0) ) CYCLE
107
108
n = GetElementNOFNodes()
109
CALL GetElementNodes( ElementNodes )
110
111
IntegStuff = GaussPoints( Element )
112
113
DO i=1,IntegStuff % n
114
U = IntegStuff % u(i)
115
V = IntegStuff % v(i)
116
W = IntegStuff % w(i)
117
118
stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &
119
Basis,dBasisdx )
120
121
NodalVar(Perm(NodeIndexes(1:n)))=&
122
NodalVar(Perm(NodeIndexes(1:n)))+ &
123
EVAR % Values(EVar % Perm(EIndex))*SqrtElementMetric*IntegStuff % s(i) * Basis(1:n)
124
125
weight(Perm(NodeIndexes(1:n)))=weight(Perm(NodeIndexes(1:n)))+&
126
SqrtElementMetric*IntegStuff % s(i) * Basis(1:n)
127
END DO
128
END DO
129
130
IF (Parallel) THEN
131
CALL ParallelSumVector(Solver % Matrix, NodalVar)
132
CALL ParallelSumVector(Solver % Matrix, weight)
133
END IF
134
135
DO i = 1, Model % NumberOfNodes
136
IF ( ABS( weight(Perm(i)) ) > 0.0D0 ) THEN
137
NVar % Values (NVar % Perm(i)) = NodalVar(Perm(i)) / weight(Perm(i))
138
END IF
139
END DO
140
141
142
END SUBROUTINE CELL_TO_NODE
143
144