New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
modupdatebasic.F in branches/dev_001_GM/AGRIF/AGRIF_FILES – NEMO

source: branches/dev_001_GM/AGRIF/AGRIF_FILES/modupdatebasic.F @ 4310

Last change on this file since 4310 was 662, checked in by opalod, 17 years ago

RB: update Agrif internal routines with a new update scheme and performance improvment

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1!
2! $Id$
3!
4C     AGRIF (Adaptive Grid Refinement In Fortran)
5C
6C     Copyright (C) 2003 Laurent Debreu (Laurent.Debreu@imag.fr)
7C                        Christophe Vouland (Christophe.Vouland@imag.fr)   
8C
9C     This program is free software; you can redistribute it and/or modify
10C     it under the terms of the GNU General Public License as published by
11C     the Free Software Foundation; either version 2 of the License, or
12C     (at your option) any later version.
13C
14C     This program is distributed in the hope that it will be useful,
15C     but WITHOUT ANY WARRANTY; without even the implied warranty of
16C     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17C     GNU General Public License for more details.
18C
19C     You should have received a copy of the GNU General Public License
20C     along with this program; if not, write to the Free Software
21C     Foundation, Inc., 59 Temple Place -  Suite 330, Boston, MA 02111-1307, USA.
22C
23C
24C
25CCC   Module Agrif_Updatebasic
26C     
27C
28      Module Agrif_Updatebasic
29C
30CCC   Description:
31CCC   Module containing different procedures of update (copy,average,
32CCC   full_weighting) used in the Agrif_Update module.
33C
34C     Modules used:
35C
36      USE Agrif_types
37     
38      IMPLICIT NONE
39C             
40
41      CONTAINS
42C     Define procedures contained in this module
43C
44C
45C
46C     ************************************************************************** 
47CCC   Subroutine Copy1d 
48C     ************************************************************************** 
49C
50      Subroutine agrif_copy1d(x,y,np,nc,
51     &                  s_parent,s_child,ds_parent,ds_child) 
52C
53CCC   Description:
54CCC   Subroutine to do a copy on a parent grid (vector x) from its child grid 
55CCC   (vector y). 
56C
57CC    Method:
58C
59C     Declarations:
60C
61     
62C       
63C     Arguments
64      INTEGER             :: np,nc     
65      REAL, DIMENSION(np) :: x     
66      REAL, DIMENSION(nc) :: y 
67      REAL                :: s_parent,s_child
68      REAL                :: ds_parent,ds_child
69C
70C     Local variables
71      INTEGER :: i,locind_child_left,coeffraf
72C 
73C
74      coeffraf = nint(ds_parent/ds_child)
75C
76      if (coeffraf == 1) then
77C
78          locind_child_left = 1 + nint((s_parent - s_child)/ds_child)
79C       
80          x(1:np) = y(locind_child_left:locind_child_left+np-1)
81C
82          return
83C
84      endif
85C
86     
87      locind_child_left = 1 + nint((s_parent - s_child)/ds_child)
88     
89      do i = 1,np
90C     
91         x(i) = y(locind_child_left)
92C
93         locind_child_left = locind_child_left + coeffraf
94C         
95      enddo   
96       
97C
98      Return
99C
100C
101      End Subroutine agrif_copy1d
102C
103C
104C
105C     ************************************************************************** 
106CCC   Subroutine Average1d 
107C     ************************************************************************** 
108C   
109      Subroutine average1d(x,y,np,nc,
110     &                     s_parent,s_child,ds_parent,ds_child) 
111C
112CCC   Description:
113CCC   Subroutine to do an update by average on a parent grid (vector x)from its 
114CCC   child grid (vector y).
115C
116C     Arguments
117      INTEGER             :: np,nc     
118      REAL, DIMENSION(np) :: x     
119      REAL, DIMENSION(nc) :: y 
120      REAL                :: s_parent,s_child
121      REAL                :: ds_parent,ds_child
122C
123C     Local variables
124      INTEGER :: i,locind_child_left,coeffraf,ii
125      REAL    :: xpos 
126      INTEGER :: nbnonnuls
127      INTEGER :: diffmod
128C 
129C
130      coeffraf = nint(ds_parent/ds_child)
131C
132      if (coeffraf == 1) then
133C
134          locind_child_left = 1 + nint((s_parent - s_child)/ds_child)
135C       
136          x(1:np) = y(locind_child_left:locind_child_left+np-1)
137C
138          return
139C
140      endif
141C
142      xpos = s_parent     
143     
144      x = 0.
145C
146      diffmod = 0
147     
148      IF ( mod(coeffraf,2) == 0 ) diffmod = 1
149
150        locind_child_left = 1 + agrif_int((xpos - s_child)/ds_child)
151     
152      do i = 1,np
153C
154
155C
156c        if ((locind_child_left-1 < 1) 
157c     &      .OR. (locind_child_left+1 > nc)) then
158C
159c            x(i) = y(locind_child_left)               
160C
161c          else
162          nbnonnuls = 0
163          Do ii = -coeffraf/2+locind_child_left+diffmod,
164     &                coeffraf/2+locind_child_left
165C 
166            IF (Agrif_UseSpecialValueInUpdate) THEN
167            IF (y(ii) .NE. Agrif_SpecialValueFineGrid) THEN
168               nbnonnuls = nbnonnuls + 1
169               x(i) = x(i) + y(ii)
170            ENDIF
171            ELSE
172               x(i) = x(i) + y(ii)
173            ENDIF
174          End Do
175            IF (Agrif_UseSpecialValueInUpdate) THEN
176                 IF (nbnonnuls .NE. 0) THEN
177                    x(i) = x(i)/nbnonnuls
178                 ELSE
179                    x(i) = Agrif_SpecialValueFineGrid
180                 ENDIF
181            ELSE
182                 x(i) = x(i)/coeffraf
183            ENDIF
184C
185c       endif
186C
187c        xpos = xpos + ds_parent
188        locind_child_left = locind_child_left + coeffraf
189C
190      enddo
191C
192      Return
193C           
194C     
195      End Subroutine average1d
196C
197C
198C
199C     ************************************************************************** 
200CCC   Subroutine Full_weighting1d 
201C     ************************************************************************** 
202C
203      Subroutine full_weighting1D(x,y,np,nc,
204     &                            s_parent,s_child,ds_parent,ds_child,
205     &                            coeffraf,locind_child_left) 
206C
207CCC   Description:
208CCC   Subroutine to do an update by full_weighting on a parent grid (vector x) 
209CCC   from its child grid (vector y).
210C 
211C     Arguments
212      INTEGER             :: np,nc     
213      REAL, DIMENSION(np) :: x     
214      REAL, DIMENSION(nc) :: y 
215      REAL                :: s_parent,s_child
216      REAL                :: ds_parent,ds_child
217C
218C     Local variables
219      INTEGER :: i,locind_child_left,coeffraf
220      REAL    :: xpos,sumweight,weight
221      INTEGER :: ii,diffmod
222      REAL :: xposfin
223      INTEGER :: it1,it2
224      INTEGER :: i1,i2
225      REAL :: invsumweight
226      REAL :: weights(-(coeffraf-1):coeffraf-1)
227     
228C
229C
230      if (coeffraf == 1) then
231C       
232          x(1:np) = y(locind_child_left:locind_child_left+np-1)
233C
234          return
235C
236      endif
237C
238      xpos = s_parent     
239     
240       x = 0.
241
242       xposfin = s_child + ds_child * (locind_child_left - 1)
243       IF (abs(xposfin - xpos).LT.0.001) THEN
244          diffmod = 0
245       ELSE
246          diffmod = 1
247       ENDIF
248C
249             
250       it1 = -(coeffraf-1)
251       i1 = -(coeffraf-1)+locind_child_left+diffmod
252       i2 = 2*coeffraf - 2
253       
254      invsumweight=1./coeffraf**2
255      do i=-(coeffraf-1),0
256        weights(i) = invsumweight*(coeffraf + i)
257      enddo
258      do i=1,coeffraf-1
259        weights(i) = invsumweight*(coeffraf - i)
260      enddo
261
262      sumweight = 0                   
263      do i = 1,np
264C
265          it2 = it1
266          Do ii = i1,i1+i2
267C
268           IF (Agrif_UseSpecialValueInUpdate) THEN
269            IF (y(ii) .NE. Agrif_SpecialValueFineGrid) THEN
270               x(i) = x(i) + weights(it2)*y(ii)
271               sumweight = sumweight+weights(it2)
272            ENDIF
273           ELSE           
274               x(i) = x(i) + weights(it2)*y(ii)
275           ENDIF           
276           
277          it2 = it2+1
278          End Do
279
280           IF (Agrif_UseSpecialValueInUpdate) THEN         
281                 IF (sumweight .NE. 0.) THEN
282                    x(i) = x(i)/sumweight
283                    sumweight = 0
284                 ELSE
285                    x(i) = Agrif_SpecialValueFineGrid
286                 ENDIF
287           ENDIF
288       
289        i1 = i1 + coeffraf
290C
291      enddo   
292C
293      Return
294C           
295C
296      End Subroutine full_weighting1D 
297
298C
299      End module AGRIF_updatebasic
Note: See TracBrowser for help on using the repository browser.