Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/IceSheet/Tools/ConservativeInterpolation/MakeCDOGridDesc.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
! Write the grid description file for CDO (https://code.mpimet.mpg.de/projects/cdo)
32
! cf e.g. http://www.climate-cryosphere.org/wiki/index.php?title=Regridding_with_CDO
33
! Limitations: restricted to meshes with 303 elements
34
! Requires: fortrangis (http://fortrangis.sourceforge.net) with proj support
35
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
36
SUBROUTINE MakeCDOGridDesc( Model,Solver,dt,TransientSimulation )
37
USE DefUtils
38
USE fortranc
39
USE proj
40
IMPLICIT NONE
41
42
TYPE(Model_t) :: Model
43
TYPE(Solver_t):: Solver
44
REAL(KIND=dp) :: dt
45
LOGICAL :: TransientSimulation
46
47
TYPE(ValueList_t), POINTER :: SolverParams
48
INTEGER :: t,n,ne,i
49
TYPE(Element_t),POINTER :: Element
50
INTEGER, POINTER :: NodeIndexes(:)
51
REAL(KIND=dp),ALLOCATABLE :: LatLon(:,:),Corner(:,:,:)
52
REAL(KIND=dp) :: x(3),y(3),xg,yg,xt(3),yt(3)
53
INTEGER, parameter :: io=12
54
INTEGER :: nclock=0
55
CHARACTER(len=100) :: Filename
56
57
TYPE(pjuv_object) :: coordp,coordg
58
TYPE(pj_object) :: pj
59
CHARACTER(LEN=MAX_NAME_LEN) :: proj_string
60
61
! Get projection definition
62
SolverParams => GetSolverParams()
63
proj_string = ListGetString(SolverParams,'projection',UnFoundFatal=.TRUE.)
64
pj = pj_init_plus(TRIM(proj_string)//CHAR(0))
65
66
ne=GetNOFActive()
67
allocate(LatLon(ne,2),Corner(ne,3,2))
68
69
DO t = 1,ne
70
Element => GetActiveElement(t)
71
NodeIndexes => Element % NodeIndexes
72
73
IF (Element % TYPE % ElementCode.NE.303) &
74
CALL FATAL('MakeCDOGrid','Wrong element type')
75
76
n = GetElementNOFNodes()
77
! element center
78
xg=SUM(Solver%Mesh%Nodes%x(NodeIndexes(1:n)))/n
79
yg=SUM(Solver%Mesh%Nodes%y(NodeIndexes(1:n)))/n
80
81
! convert to lon,lat
82
coordp = pjuv_object(xg,yg)
83
coordg = pj_inv(coordp, pj)
84
LatLon(t,1)=coordg % v * pj_rad_to_deg
85
LatLon(t,2)=coordg % u * pj_rad_to_deg
86
87
! element corners
88
x(1:n)=Solver%Mesh%Nodes%x(NodeIndexes(1:n))
89
y(1:n)=Solver%Mesh%Nodes%y(NodeIndexes(1:n))
90
! CDO requires anti-clokwise ordering
91
IF(IsClockwise(x,y,n)) THEN
92
nclock=nclock+1
93
xt=x
94
yt=y
95
Do i=1,3
96
x(4-i)=xt(i)
97
y(4-i)=yt(i)
98
End do
99
END IF
100
!convert corners to lon,lat
101
Do i=1,n
102
coordp = pjuv_object(x(i),y(i))
103
coordg = pj_inv(coordp, pj)
104
Corner(t,i,1)=coordg % v * pj_rad_to_deg
105
Corner(t,i,2)=coordg % u * pj_rad_to_deg
106
End do
107
108
End do
109
110
PRINT *,Model%Mesh%name
111
! write the grid description file
112
IF (ParEnv % Pes>1 ) THEN
113
write(FileName,'(a,a,i0,a)') TRIM(Model%Mesh%name),'_CDOGrid_',ParEnv%MyPe,'.txt'
114
ELSE
115
write(FileName,'(a,a)') TRIM(Model%Mesh%name),'_CDOGrid.txt'
116
END IF
117
118
open(io,file=trim(Filename))
119
write(io,*) 'gridtype = unstructured'
120
write(io,*) 'gridsize = ',ne
121
write(io,*) 'nvertex = ',3
122
123
write(io,*) 'xvals = ',LatLon(1,2)
124
Do t=2,ne
125
write(io,*) LatLon(t,2)
126
End do
127
write(io,*) 'xbounds = ',Corner(1,1:3,2)
128
Do t=2,ne
129
write(io,*) Corner(t,1:3,2)
130
End do
131
132
write(io,*) 'yvals = ',LatLon(1,1)
133
Do t=2,ne
134
write(io,*) LatLon(t,1)
135
End do
136
write(io,*) 'ybounds = ',Corner(1,1:3,1)
137
Do t=2,ne
138
write(io,*) Corner(t,1:3,1)
139
End do
140
141
142
close(io)
143
144
deallocate(LatLon,Corner)
145
146
CONTAINS
147
! Are nodes given clockwise?
148
FUNCTION IsClockwise(x,y,n) RESULT(clokwise)
149
LOGICAL :: clokwise
150
REAL(KIND=dp) :: x(n),y(n)
151
INTEGER :: n
152
INTEGER :: i,ind2
153
REAL(KIND=dp) :: sarea
154
155
sarea=0._dp
156
Do i=1,n-1
157
ind2=mod(i+1,n)
158
sarea=sarea+(x(ind2)-x(i))*(y(ind2)+y(i))
159
End do
160
clokwise=(sarea.GT.0)
161
162
END FUNCTION IsClockwise
163
End
164
165