xref: /libCEED/tests/t524-operator-f.f90 (revision 872c4ebb6cdbee8c5ec55e4968c9ca6dcb49c96c)
1250756a7Sjeremylt!-----------------------------------------------------------------------
2250756a7Sjeremylt!
3250756a7Sjeremylt! Header with common subroutine
4250756a7Sjeremylt!
5250756a7Sjeremylt      include 't320-basis-f.h'
6250756a7Sjeremylt!-----------------------------------------------------------------------
7250756a7Sjeremylt      subroutine setup(ctx,q,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,&
8250756a7Sjeremylt&           u15,u16,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,ierr)
9250756a7Sjeremylt      real*8 ctx
10250756a7Sjeremylt      real*8 u1(1)
11250756a7Sjeremylt      real*8 u2(1)
12250756a7Sjeremylt      real*8 v1(1)
13250756a7Sjeremylt      integer q,ierr
14250756a7Sjeremylt
15250756a7Sjeremylt      do i=1,q
16250756a7Sjeremylt        v1(i)=u1(i)*(u2(i+q*0)*u2(i+q*3)-u2(i+q*1)*u2(i+q*2))
17250756a7Sjeremylt      enddo
18250756a7Sjeremylt
19250756a7Sjeremylt      ierr=0
20250756a7Sjeremylt      end
21250756a7Sjeremylt!-----------------------------------------------------------------------
22250756a7Sjeremylt      subroutine mass(ctx,q,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,&
23250756a7Sjeremylt&           u15,u16,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,ierr)
24250756a7Sjeremylt      real*8 ctx
25250756a7Sjeremylt      real*8 u1(1)
26250756a7Sjeremylt      real*8 u2(1)
27250756a7Sjeremylt      real*8 v1(1)
28250756a7Sjeremylt      integer q,ierr
29250756a7Sjeremylt
30250756a7Sjeremylt      do i=1,q
31250756a7Sjeremylt        v1(i)=u2(i)*u1(i)
32250756a7Sjeremylt      enddo
33250756a7Sjeremylt
34250756a7Sjeremylt      ierr=0
35250756a7Sjeremylt      end
36250756a7Sjeremylt!-----------------------------------------------------------------------
37250756a7Sjeremylt      program test
38250756a7Sjeremylt
39250756a7Sjeremylt      include 'ceedf.h'
40250756a7Sjeremylt
41250756a7Sjeremylt      integer ceed,err,i,j,k
42250756a7Sjeremylt      integer erestrictxtet,erestrictutet,erestrictxitet,erestrictuitet,&
43250756a7Sjeremylt&             erestrictxhex,erestrictuhex,erestrictxihex,erestrictuihex
44250756a7Sjeremylt      integer bxtet,butet,bxhex,buhex
45250756a7Sjeremylt      integer qf_setuptet,qf_masstet,qf_setuphex,qf_masshex
46250756a7Sjeremylt      integer op_setuptet,op_masstet,op_setuphex,op_masshex,op_setup,op_mass
47250756a7Sjeremylt      integer qdatatet,qdatahex,x,u,v
48250756a7Sjeremylt      integer nelemtet,nelemhex,ptet,phex,qtet,qhex,d
49250756a7Sjeremylt      integer row,col,offset
50250756a7Sjeremylt      parameter(nelemtet=6)
51250756a7Sjeremylt      parameter(ptet=6)
52250756a7Sjeremylt      parameter(qtet=4)
53250756a7Sjeremylt      parameter(nelemhex=6)
54250756a7Sjeremylt      parameter(phex=3)
55250756a7Sjeremylt      parameter(qhex=4)
56250756a7Sjeremylt      parameter(d=2)
57250756a7Sjeremylt      integer ndofs,nqptstet,nqptshex,nqpts,nx,ny,nxtet,nytet,nxhex
58250756a7Sjeremylt      parameter(nx=3)
59250756a7Sjeremylt      parameter(ny=3)
60250756a7Sjeremylt      parameter(nxtet=3)
61250756a7Sjeremylt      parameter(nytet=1)
62250756a7Sjeremylt      parameter(nxhex=3)
63250756a7Sjeremylt      parameter(ndofs=(nx*2+1)*(ny*2+1))
64250756a7Sjeremylt      parameter(nqptstet=nelemtet*qtet)
65250756a7Sjeremylt      parameter(nqptshex=nelemhex*qhex*qhex)
66250756a7Sjeremylt      parameter(nqpts=nqptstet+nqptshex)
67250756a7Sjeremylt      integer indxtet(nelemtet*ptet),indxhex(nelemhex*phex*phex)
68250756a7Sjeremylt      real*8 arrx(d*ndofs)
69250756a7Sjeremylt      integer*8 voffset,xoffset
70250756a7Sjeremylt
71250756a7Sjeremylt      real*8 qref(d*qtet)
72250756a7Sjeremylt      real*8 qweight(qtet)
73250756a7Sjeremylt      real*8 interp(ptet*qtet)
74250756a7Sjeremylt      real*8 grad(d*ptet*qtet)
75250756a7Sjeremylt
76250756a7Sjeremylt      real*8 hv(ndofs)
77250756a7Sjeremylt      real*8 total
78250756a7Sjeremylt
79250756a7Sjeremylt      character arg*32
80250756a7Sjeremylt
81250756a7Sjeremylt      external setup,mass
82250756a7Sjeremylt
83250756a7Sjeremylt      call getarg(1,arg)
84250756a7Sjeremylt
85250756a7Sjeremylt      call ceedinit(trim(arg)//char(0),ceed,err)
86250756a7Sjeremylt
87250756a7Sjeremylt! DoF Coordinates
88250756a7Sjeremylt      do i=0,ny*2
89250756a7Sjeremylt        do j=0,nx*2
90250756a7Sjeremylt          arrx(i+j*(ny*2+1)+0*ndofs+1)=1.d0*i/(2*ny)
91250756a7Sjeremylt          arrx(i+j*(ny*2+1)+1*ndofs+1)=1.d0*j/(2*nx)
92250756a7Sjeremylt        enddo
93250756a7Sjeremylt      enddo
94250756a7Sjeremylt
95250756a7Sjeremylt      call ceedvectorcreate(ceed,d*ndofs,x,err)
96250756a7Sjeremylt      xoffset=0
97250756a7Sjeremylt      call ceedvectorsetarray(x,ceed_mem_host,ceed_use_pointer,arrx,xoffset,err)
98250756a7Sjeremylt
99250756a7Sjeremylt! Qdata Vectors
100250756a7Sjeremylt      call ceedvectorcreate(ceed,nqptstet,qdatatet,err)
101250756a7Sjeremylt      call ceedvectorcreate(ceed,nqptshex,qdatahex,err)
102250756a7Sjeremylt
103250756a7Sjeremylt! Tet Elements
104250756a7Sjeremylt      do i=0,2
105250756a7Sjeremylt        col=mod(i,nx)
106250756a7Sjeremylt        row=i/nx
107250756a7Sjeremylt        offset=col*2+row*(nx*2+1)*2
108250756a7Sjeremylt
109250756a7Sjeremylt        indxtet(i*2*ptet+1)=2+offset
110250756a7Sjeremylt        indxtet(i*2*ptet+2)=9+offset
111250756a7Sjeremylt        indxtet(i*2*ptet+3)=16+offset
112250756a7Sjeremylt        indxtet(i*2*ptet+4)=1+offset
113250756a7Sjeremylt        indxtet(i*2*ptet+5)=8+offset
114250756a7Sjeremylt        indxtet(i*2*ptet+6)=0+offset
115250756a7Sjeremylt
116250756a7Sjeremylt        indxtet(i*2*ptet+7)=14+offset
117250756a7Sjeremylt        indxtet(i*2*ptet+8)=7+offset
118250756a7Sjeremylt        indxtet(i*2*ptet+9)=0+offset
119250756a7Sjeremylt        indxtet(i*2*ptet+10)=15+offset
120250756a7Sjeremylt        indxtet(i*2*ptet+11)=8+offset
121250756a7Sjeremylt        indxtet(i*2*ptet+12)=16+offset
122250756a7Sjeremylt      enddo
123250756a7Sjeremylt
124250756a7Sjeremylt! -- Restrictions
125250756a7Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemtet,ptet,ndofs,d,ceed_mem_host,&
126250756a7Sjeremylt     & ceed_use_pointer,indxtet,erestrictxtet,err)
127250756a7Sjeremylt      call ceedelemrestrictioncreateidentity(ceed,nelemtet,ptet,nelemtet*ptet,&
128250756a7Sjeremylt     & d,erestrictxitet,err)
129250756a7Sjeremylt
130250756a7Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemtet,ptet,ndofs,1,ceed_mem_host,&
131250756a7Sjeremylt     & ceed_use_pointer,indxtet,erestrictutet,err)
132250756a7Sjeremylt      call ceedelemrestrictioncreateidentity(ceed,nelemtet,qtet,nqptstet,1,&
133250756a7Sjeremylt     & erestrictuitet,err)
134250756a7Sjeremylt
135250756a7Sjeremylt! -- Bases
136250756a7Sjeremylt      call buildmats(qref,qweight,interp,grad)
137250756a7Sjeremylt      call ceedbasiscreateh1(ceed,ceed_triangle,d,ptet,qtet,interp,grad,qref,&
138250756a7Sjeremylt     & qweight,bxtet,err)
139250756a7Sjeremylt      call buildmats(qref,qweight,interp,grad)
140250756a7Sjeremylt      call ceedbasiscreateh1(ceed,ceed_triangle,1,ptet,qtet,interp,grad,qref,&
141250756a7Sjeremylt     & qweight,butet,err)
142250756a7Sjeremylt
143250756a7Sjeremylt! -- QFunctions
144250756a7Sjeremylt      call ceedqfunctioncreateinterior(ceed,1,setup,&
145250756a7Sjeremylt     &SOURCE_DIR&
146250756a7Sjeremylt     &//'t510-operator.h:setup'//char(0),qf_setuptet,err)
147250756a7Sjeremylt      call ceedqfunctionaddinput(qf_setuptet,'_weight',1,ceed_eval_weight,err)
148250756a7Sjeremylt      call ceedqfunctionaddinput(qf_setuptet,'dx',d*d,ceed_eval_grad,err)
149250756a7Sjeremylt      call ceedqfunctionaddoutput(qf_setuptet,'rho',1,ceed_eval_none,err)
150250756a7Sjeremylt
151250756a7Sjeremylt      call ceedqfunctioncreateinterior(ceed,1,mass,&
152250756a7Sjeremylt     &SOURCE_DIR&
153250756a7Sjeremylt     &//'t510-operator.h:mass'//char(0),qf_masstet,err)
154250756a7Sjeremylt      call ceedqfunctionaddinput(qf_masstet,'rho',1,ceed_eval_none,err)
155250756a7Sjeremylt      call ceedqfunctionaddinput(qf_masstet,'u',1,ceed_eval_interp,err)
156250756a7Sjeremylt      call ceedqfunctionaddoutput(qf_masstet,'v',1,ceed_eval_interp,err)
157250756a7Sjeremylt
158250756a7Sjeremylt! -- Operators
159250756a7Sjeremylt! ---- Setup Tet
160250756a7Sjeremylt      call ceedoperatorcreate(ceed,qf_setuptet,ceed_qfunction_none,&
161250756a7Sjeremylt     & ceed_qfunction_none,op_setuptet,err)
162250756a7Sjeremylt      call ceedoperatorsetfield(op_setuptet,'_weight',erestrictxitet,&
163250756a7Sjeremylt     & ceed_notranspose,bxtet,ceed_vector_none,err)
164250756a7Sjeremylt      call ceedoperatorsetfield(op_setuptet,'dx',erestrictxtet,&
165250756a7Sjeremylt     & ceed_notranspose,bxtet,ceed_vector_active,err)
166250756a7Sjeremylt      call ceedoperatorsetfield(op_setuptet,'rho',erestrictuitet,&
167250756a7Sjeremylt     & ceed_notranspose,ceed_basis_collocated,qdatatet,err)
168250756a7Sjeremylt! ---- Mass Tet
169250756a7Sjeremylt      call ceedoperatorcreate(ceed,qf_masstet,ceed_qfunction_none,&
170250756a7Sjeremylt     & ceed_qfunction_none,op_masstet,err)
171250756a7Sjeremylt      call ceedoperatorsetfield(op_masstet,'rho',erestrictuitet,&
172250756a7Sjeremylt     & ceed_notranspose,ceed_basis_collocated,qdatatet,err)
173250756a7Sjeremylt      call ceedoperatorsetfield(op_masstet,'u',erestrictutet,&
174250756a7Sjeremylt     & ceed_notranspose,butet,ceed_vector_active,err)
175250756a7Sjeremylt      call ceedoperatorsetfield(op_masstet,'v',erestrictutet,&
176250756a7Sjeremylt     & ceed_notranspose,butet,ceed_vector_active,err)
177250756a7Sjeremylt
178250756a7Sjeremylt! Hex Elements
179250756a7Sjeremylt      do i=0,nelemhex-1
180250756a7Sjeremylt        col=mod(i,nx)
181250756a7Sjeremylt        row=i/nx
182250756a7Sjeremylt        offset=(nxtet*2+1)*(nytet*2)*(1+row)+col*2
183250756a7Sjeremylt        do j=0,phex-1
184250756a7Sjeremylt          do k=0,phex-1
185250756a7Sjeremylt            indxhex(phex*(phex*i+k)+j+1)=offset+k*(nxhex*2+1)+j
186250756a7Sjeremylt          enddo
187250756a7Sjeremylt        enddo
188250756a7Sjeremylt      enddo
189250756a7Sjeremylt
190250756a7Sjeremylt! -- Restrictions
191250756a7Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemhex,phex*phex,ndofs,d,&
192250756a7Sjeremylt     & ceed_mem_host,ceed_use_pointer,indxhex,erestrictxhex,err)
193250756a7Sjeremylt      call ceedelemrestrictioncreateidentity(ceed,nelemhex,phex*phex,&
194250756a7Sjeremylt     & nelemhex*phex*phex,d,erestrictxihex,err)
195250756a7Sjeremylt
196250756a7Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemhex,phex*phex,ndofs,1,&
197250756a7Sjeremylt     & ceed_mem_host,ceed_use_pointer,indxhex,erestrictuhex,err)
198250756a7Sjeremylt      call ceedelemrestrictioncreateidentity(ceed,nelemhex,qhex*qhex,nqptshex,&
199250756a7Sjeremylt     & 1,erestrictuihex,err)
200250756a7Sjeremylt
201250756a7Sjeremylt! -- Bases
202250756a7Sjeremylt      call ceedbasiscreatetensorh1lagrange(ceed,d,d,phex,qhex,ceed_gauss,&
203250756a7Sjeremylt     & bxhex,err)
204250756a7Sjeremylt      call ceedbasiscreatetensorh1lagrange(ceed,d,1,phex,qhex,ceed_gauss,&
205250756a7Sjeremylt     & buhex,err)
206250756a7Sjeremylt
207250756a7Sjeremylt! -- QFunctions
208250756a7Sjeremylt      call ceedqfunctioncreateinterior(ceed,1,setup,&
209250756a7Sjeremylt     &SOURCE_DIR&
210*872c4ebbSjeremylt     &//'t510-operator.h:setup'//char(0),qf_setuphex,err)
211250756a7Sjeremylt      call ceedqfunctionaddinput(qf_setuphex,'_weight',1,ceed_eval_weight,err)
212250756a7Sjeremylt      call ceedqfunctionaddinput(qf_setuphex,'dx',d*d,ceed_eval_grad,err)
213250756a7Sjeremylt      call ceedqfunctionaddoutput(qf_setuphex,'rho',1,ceed_eval_none,err)
214250756a7Sjeremylt
215250756a7Sjeremylt      call ceedqfunctioncreateinterior(ceed,1,mass,&
216250756a7Sjeremylt     &SOURCE_DIR&
217*872c4ebbSjeremylt     &//'t510-operator.h:mass'//char(0),qf_masshex,err)
218250756a7Sjeremylt      call ceedqfunctionaddinput(qf_masshex,'rho',1,ceed_eval_none,err)
219250756a7Sjeremylt      call ceedqfunctionaddinput(qf_masshex,'u',1,ceed_eval_interp,err)
220250756a7Sjeremylt      call ceedqfunctionaddoutput(qf_masshex,'v',1,ceed_eval_interp,err)
221250756a7Sjeremylt
222250756a7Sjeremylt! -- Operators
223250756a7Sjeremylt! ---- Setup Hex
224250756a7Sjeremylt      call ceedoperatorcreate(ceed,qf_setuphex,ceed_qfunction_none,&
225250756a7Sjeremylt     & ceed_qfunction_none,op_setuphex,&
226250756a7Sjeremylt     & err)
227250756a7Sjeremylt      call ceedoperatorsetfield(op_setuphex,'_weight',erestrictxihex,&
228250756a7Sjeremylt     & ceed_notranspose,bxhex,ceed_vector_none,err)
229250756a7Sjeremylt      call ceedoperatorsetfield(op_setuphex,'dx',erestrictxhex,&
230250756a7Sjeremylt     & ceed_notranspose,bxhex,ceed_vector_active,err)
231250756a7Sjeremylt      call ceedoperatorsetfield(op_setuphex,'rho',erestrictuihex,&
232250756a7Sjeremylt     & ceed_notranspose,ceed_basis_collocated,qdatahex,err)
233250756a7Sjeremylt! ---- Mass Hex
234250756a7Sjeremylt      call ceedoperatorcreate(ceed,qf_masshex,ceed_qfunction_none,&
235250756a7Sjeremylt     & ceed_qfunction_none,op_masshex,&
236250756a7Sjeremylt     & err)
237250756a7Sjeremylt      call ceedoperatorsetfield(op_masshex,'rho',erestrictuihex,&
238250756a7Sjeremylt     & ceed_notranspose,ceed_basis_collocated,qdatahex,err)
239250756a7Sjeremylt      call ceedoperatorsetfield(op_masshex,'u',erestrictuhex,&
240250756a7Sjeremylt     & ceed_notranspose,buhex,ceed_vector_active,err)
241250756a7Sjeremylt      call ceedoperatorsetfield(op_masshex,'v',erestrictuhex,&
242250756a7Sjeremylt     & ceed_notranspose,buhex,ceed_vector_active,err)
243250756a7Sjeremylt
244250756a7Sjeremylt! Composite Operators
245250756a7Sjeremylt      call ceedcompositeoperatorcreate(ceed,op_setup,err)
246250756a7Sjeremylt      call ceedcompositeoperatoraddsub(op_setup,op_setuptet,err)
247250756a7Sjeremylt      call ceedcompositeoperatoraddsub(op_setup,op_setuphex,err)
248250756a7Sjeremylt
249250756a7Sjeremylt      call ceedcompositeoperatorcreate(ceed,op_mass,err)
250250756a7Sjeremylt      call ceedcompositeoperatoraddsub(op_mass,op_masstet,err)
251250756a7Sjeremylt      call ceedcompositeoperatoraddsub(op_mass,op_masshex,err)
252250756a7Sjeremylt
253250756a7Sjeremylt! Apply Setup Operator
254250756a7Sjeremylt      call ceedoperatorapply(op_setup,x,ceed_vector_none,&
255250756a7Sjeremylt     & ceed_request_immediate,err)
256250756a7Sjeremylt
257250756a7Sjeremylt! Apply Mass Operator
258250756a7Sjeremylt      call ceedvectorcreate(ceed,ndofs,u,err)
259250756a7Sjeremylt      call ceedvectorsetvalue(u,1.d0,err)
260250756a7Sjeremylt      call ceedvectorcreate(ceed,ndofs,v,err)
261250756a7Sjeremylt      call ceedvectorsetvalue(v,0.d0,err)
262250756a7Sjeremylt
263250756a7Sjeremylt      call ceedoperatorapplyadd(op_mass,u,v,ceed_request_immediate,err)
264250756a7Sjeremylt
265250756a7Sjeremylt! Check Output
266250756a7Sjeremylt      call ceedvectorgetarrayread(v,ceed_mem_host,hv,voffset,err)
267250756a7Sjeremylt      total=0.
268250756a7Sjeremylt      do i=1,ndofs
269250756a7Sjeremylt        total=total+hv(voffset+i)
270250756a7Sjeremylt      enddo
271250756a7Sjeremylt      if (abs(total-1.)>1.0d-10) then
272250756a7Sjeremylt! LCOV_EXCL_START
273250756a7Sjeremylt        write(*,*) 'Computed Area: ',total,' != True Area: 1.0'
274250756a7Sjeremylt! LCOV_EXCL_STOP
275250756a7Sjeremylt      endif
276250756a7Sjeremylt      call ceedvectorrestorearrayread(v,hv,voffset,err)
277250756a7Sjeremylt
278250756a7Sjeremylt      call ceedvectorsetvalue(v,1.d0,err)
279250756a7Sjeremylt      call ceedoperatorapplyadd(op_mass,u,v,ceed_request_immediate,err)
280250756a7Sjeremylt
281250756a7Sjeremylt! Check Output
282250756a7Sjeremylt      call ceedvectorgetarrayread(v,ceed_mem_host,hv,voffset,err)
283250756a7Sjeremylt      total=-ndofs
284250756a7Sjeremylt      do i=1,ndofs
285250756a7Sjeremylt        total=total+hv(voffset+i)
286250756a7Sjeremylt      enddo
287250756a7Sjeremylt      if (abs(total-1.)>1.0d-10) then
288250756a7Sjeremylt! LCOV_EXCL_START
289250756a7Sjeremylt        write(*,*) 'Computed Area: ',total,' != True Area: 1.0'
290250756a7Sjeremylt! LCOV_EXCL_STOP
291250756a7Sjeremylt      endif
292250756a7Sjeremylt      call ceedvectorrestorearrayread(v,hv,voffset,err)
293250756a7Sjeremylt
294250756a7Sjeremylt! Cleanup
295250756a7Sjeremylt      call ceedqfunctiondestroy(qf_setuptet,err)
296250756a7Sjeremylt      call ceedqfunctiondestroy(qf_masstet,err)
297250756a7Sjeremylt      call ceedoperatordestroy(op_setuptet,err)
298250756a7Sjeremylt      call ceedoperatordestroy(op_masstet,err)
299250756a7Sjeremylt      call ceedqfunctiondestroy(qf_setuphex,err)
300250756a7Sjeremylt      call ceedqfunctiondestroy(qf_masshex,err)
301250756a7Sjeremylt      call ceedoperatordestroy(op_setuphex,err)
302250756a7Sjeremylt      call ceedoperatordestroy(op_masshex,err)
303250756a7Sjeremylt      call ceedoperatordestroy(op_setup,err)
304250756a7Sjeremylt      call ceedoperatordestroy(op_mass,err)
305250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictutet,err)
306250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictxtet,err)
307250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictuitet,err)
308250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictxitet,err)
309250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictuhex,err)
310250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictxhex,err)
311250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictuihex,err)
312250756a7Sjeremylt      call ceedelemrestrictiondestroy(erestrictxihex,err)
313250756a7Sjeremylt      call ceedbasisdestroy(butet,err)
314250756a7Sjeremylt      call ceedbasisdestroy(bxtet,err)
315250756a7Sjeremylt      call ceedbasisdestroy(buhex,err)
316250756a7Sjeremylt      call ceedbasisdestroy(bxhex,err)
317250756a7Sjeremylt      call ceedvectordestroy(x,err)
318250756a7Sjeremylt      call ceedvectordestroy(u,err)
319250756a7Sjeremylt      call ceedvectordestroy(v,err)
320250756a7Sjeremylt      call ceedvectordestroy(qdatatet,err)
321250756a7Sjeremylt      call ceedvectordestroy(qdatahex,err)
322250756a7Sjeremylt      call ceeddestroy(ceed,err)
323250756a7Sjeremylt      end
324250756a7Sjeremylt!-----------------------------------------------------------------------
325