xref: /libCEED/tests/t522-operator-f.f90 (revision d979a0510f6353f9b8b50621433d53955a3f350a)
1b6faaefaSjeremylt!-----------------------------------------------------------------------
2b6faaefaSjeremylt!
3b6faaefaSjeremylt! Header with common subroutine
4b6faaefaSjeremylt!
5b6faaefaSjeremylt      include 't320-basis-f.h'
6b6faaefaSjeremylt!-----------------------------------------------------------------------
7b6faaefaSjeremylt      subroutine setup(ctx,q,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,&
8b6faaefaSjeremylt&           u15,u16,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,ierr)
9b6faaefaSjeremylt      real*8 ctx
10b6faaefaSjeremylt      real*8 u1(1)
11b6faaefaSjeremylt      real*8 u2(1)
12b6faaefaSjeremylt      real*8 v1(1)
13b6faaefaSjeremylt      real*8 w
14b6faaefaSjeremylt      integer q,ierr
15b6faaefaSjeremylt
16b6faaefaSjeremylt      do i=1,q
17b6faaefaSjeremylt        w = u1(i)/(u2(i+0*q)*u2(i+3*q)-u2(i+1*q)*u2(i+2*q))
18b6faaefaSjeremylt        v1(i+0*q)=w*(u2(i+2*q)*u2(i+2*q)+u2(i+3*q)*u2(i+3*q))
19b6faaefaSjeremylt        v1(i+1*q)=w*(u2(i+0*q)*u2(i+0*q)+u2(i+1*q)*u2(i+1*q))
20b6faaefaSjeremylt        v1(i+2*q)=w*(u2(i+0*q)*u2(i+2*q)+u2(i+1*q)*u2(i+3*q))
21b6faaefaSjeremylt      enddo
22b6faaefaSjeremylt
23b6faaefaSjeremylt      ierr=0
24b6faaefaSjeremylt      end
25b6faaefaSjeremylt!-----------------------------------------------------------------------
26b6faaefaSjeremylt      subroutine diff(ctx,q,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,&
27b6faaefaSjeremylt&           u15,u16,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,ierr)
28b6faaefaSjeremylt      real*8 ctx
29b6faaefaSjeremylt      real*8 u1(1)
30b6faaefaSjeremylt      real*8 u2(1)
31b6faaefaSjeremylt      real*8 v1(1)
32b6faaefaSjeremylt      integer q,ierr
33b6faaefaSjeremylt
34b6faaefaSjeremylt      do i=1,q
35b6faaefaSjeremylt        v1(i+0*q)=u1(i+0*q)*u2(i+0*q)+u1(i+2*q)*u2(i+1*q)
36b6faaefaSjeremylt        v1(i+1*q)=u1(i+2*q)*u2(i+0*q)+u1(i+1*q)*u2(i+1*q)
37b6faaefaSjeremylt      enddo
38b6faaefaSjeremylt
39b6faaefaSjeremylt      ierr=0
40b6faaefaSjeremylt      end
41b6faaefaSjeremylt!-----------------------------------------------------------------------
42b6faaefaSjeremylt      program test
43b6faaefaSjeremylt
44b6faaefaSjeremylt      include 'ceedf.h'
45b6faaefaSjeremylt
46b6faaefaSjeremylt      integer ceed,err,i,j,k
4715910d16Sjeremylt      integer stridesqdtet(3),stridesqdhex(3)
4815910d16Sjeremylt      integer erestrictxtet,erestrictutet,erestrictqditet,&
4915910d16Sjeremylt&             erestrictxhex,erestrictuhex,erestrictqdihex
50b6faaefaSjeremylt      integer bxtet,butet,bxhex,buhex
51b6faaefaSjeremylt      integer qf_setuptet,qf_difftet,qf_setuphex,qf_diffhex
52b6faaefaSjeremylt      integer op_setuptet,op_difftet,op_setuphex,op_diffhex,op_setup,op_diff
53b6faaefaSjeremylt      integer qdatatet,qdatahex,x,u,v
54b6faaefaSjeremylt      integer nelemtet,nelemhex,ptet,phex,qtet,qhex,d
55b6faaefaSjeremylt      integer row,col,offset
56b6faaefaSjeremylt      parameter(nelemtet=6)
57b6faaefaSjeremylt      parameter(ptet=6)
58b6faaefaSjeremylt      parameter(qtet=4)
59b6faaefaSjeremylt      parameter(nelemhex=6)
60b6faaefaSjeremylt      parameter(phex=3)
61b6faaefaSjeremylt      parameter(qhex=4)
62b6faaefaSjeremylt      parameter(d=2)
63b6faaefaSjeremylt      integer ndofs,nqptstet,nqptshex,nqpts,nx,ny,nxtet,nytet,nxhex
64b6faaefaSjeremylt      parameter(nx=3)
65b6faaefaSjeremylt      parameter(ny=3)
66b6faaefaSjeremylt      parameter(nxtet=3)
67b6faaefaSjeremylt      parameter(nytet=1)
68b6faaefaSjeremylt      parameter(nxhex=3)
69b6faaefaSjeremylt      parameter(ndofs=(nx*2+1)*(ny*2+1))
70b6faaefaSjeremylt      parameter(nqptstet=nelemtet*qtet)
71b6faaefaSjeremylt      parameter(nqptshex=nelemhex*qhex*qhex)
72b6faaefaSjeremylt      parameter(nqpts=nqptstet+nqptshex)
73b6faaefaSjeremylt      integer indxtet(nelemtet*ptet),indxhex(nelemhex*phex*phex)
74b6faaefaSjeremylt      real*8 arrx(d*ndofs)
75b6faaefaSjeremylt      integer*8 voffset,xoffset
76b6faaefaSjeremylt
77b6faaefaSjeremylt      real*8 qref(d*qtet)
78b6faaefaSjeremylt      real*8 qweight(qtet)
79b6faaefaSjeremylt      real*8 interp(ptet*qtet)
80b6faaefaSjeremylt      real*8 grad(d*ptet*qtet)
81b6faaefaSjeremylt
82b6faaefaSjeremylt      real*8 hv(ndofs)
83b6faaefaSjeremylt      real*8 total
84b6faaefaSjeremylt
85b6faaefaSjeremylt      character arg*32
86b6faaefaSjeremylt
87b6faaefaSjeremylt      external setup,diff
88b6faaefaSjeremylt
89b6faaefaSjeremylt      call getarg(1,arg)
90b6faaefaSjeremylt
91b6faaefaSjeremylt      call ceedinit(trim(arg)//char(0),ceed,err)
92b6faaefaSjeremylt
93b6faaefaSjeremylt! DoF Coordinates
94b6faaefaSjeremylt      do i=0,ny*2
95b6faaefaSjeremylt        do j=0,nx*2
96b6faaefaSjeremylt          arrx(i+j*(ny*2+1)+0*ndofs+1)=1.d0*i/(2*ny)
97b6faaefaSjeremylt          arrx(i+j*(ny*2+1)+1*ndofs+1)=1.d0*j/(2*nx)
98b6faaefaSjeremylt        enddo
99b6faaefaSjeremylt      enddo
100b6faaefaSjeremylt
101b6faaefaSjeremylt      call ceedvectorcreate(ceed,d*ndofs,x,err)
102b6faaefaSjeremylt      xoffset=0
103b6faaefaSjeremylt      call ceedvectorsetarray(x,ceed_mem_host,ceed_use_pointer,arrx,xoffset,err)
104b6faaefaSjeremylt
105b6faaefaSjeremylt! Qdata Vectors
106b6faaefaSjeremylt      call ceedvectorcreate(ceed,nqptstet*d*(d+1)/2,qdatatet,err)
107b6faaefaSjeremylt      call ceedvectorcreate(ceed,nqptshex*d*(d+1)/2,qdatahex,err)
108b6faaefaSjeremylt
109b6faaefaSjeremylt! Tet Elements
110b6faaefaSjeremylt      do i=0,2
111b6faaefaSjeremylt        col=mod(i,nx)
112b6faaefaSjeremylt        row=i/nx
113b6faaefaSjeremylt        offset=col*2+row*(nx*2+1)*2
114b6faaefaSjeremylt
115b6faaefaSjeremylt        indxtet(i*2*ptet+1)=2+offset
116b6faaefaSjeremylt        indxtet(i*2*ptet+2)=9+offset
117b6faaefaSjeremylt        indxtet(i*2*ptet+3)=16+offset
118b6faaefaSjeremylt        indxtet(i*2*ptet+4)=1+offset
119b6faaefaSjeremylt        indxtet(i*2*ptet+5)=8+offset
120b6faaefaSjeremylt        indxtet(i*2*ptet+6)=0+offset
121b6faaefaSjeremylt
122b6faaefaSjeremylt        indxtet(i*2*ptet+7)=14+offset
123b6faaefaSjeremylt        indxtet(i*2*ptet+8)=7+offset
124b6faaefaSjeremylt        indxtet(i*2*ptet+9)=0+offset
125b6faaefaSjeremylt        indxtet(i*2*ptet+10)=15+offset
126b6faaefaSjeremylt        indxtet(i*2*ptet+11)=8+offset
127b6faaefaSjeremylt        indxtet(i*2*ptet+12)=16+offset
128b6faaefaSjeremylt      enddo
129b6faaefaSjeremylt
130b6faaefaSjeremylt! -- Restrictions
131*d979a051Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemtet,ptet,d,ndofs,d*ndofs,&
132a8d32208Sjeremylt     & ceed_mem_host,ceed_use_pointer,indxtet,erestrictxtet,err)
133b6faaefaSjeremylt
134*d979a051Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemtet,ptet,1,1,ndofs,&
135a8d32208Sjeremylt     & ceed_mem_host,ceed_use_pointer,indxtet,erestrictutet,err)
1367509a596Sjeremylt      stridesqdtet=[1,qtet,qtet*d*(d+1)/2]
137*d979a051Sjeremylt      call ceedelemrestrictioncreatestrided(ceed,nelemtet,qtet,d*(d+1)/2,&
138*d979a051Sjeremylt     & d*(d+1)/2*nqptstet,stridesqdtet,erestrictqditet,err)
139b6faaefaSjeremylt
140b6faaefaSjeremylt! -- Bases
141b6faaefaSjeremylt      call buildmats(qref,qweight,interp,grad)
142b6faaefaSjeremylt      call ceedbasiscreateh1(ceed,ceed_triangle,d,ptet,qtet,interp,grad,qref,&
143b6faaefaSjeremylt     & qweight,bxtet,err)
144b6faaefaSjeremylt      call buildmats(qref,qweight,interp,grad)
145b6faaefaSjeremylt      call ceedbasiscreateh1(ceed,ceed_triangle,1,ptet,qtet,interp,grad,qref,&
146b6faaefaSjeremylt     & qweight,butet,err)
147b6faaefaSjeremylt
148b6faaefaSjeremylt! -- QFunctions
149b6faaefaSjeremylt      call ceedqfunctioncreateinterior(ceed,1,setup,&
150b6faaefaSjeremylt     &SOURCE_DIR&
151a05f9790Sjeremylt     &//'t522-operator.h:setup'//char(0),qf_setuptet,err)
152b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_setuptet,'_weight',1,ceed_eval_weight,err)
153b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_setuptet,'dx',d*d,ceed_eval_grad,err)
154b6faaefaSjeremylt      call ceedqfunctionaddoutput(qf_setuptet,'rho',d*(d+1)/2,ceed_eval_none,&
155b6faaefaSjeremylt     & err)
156b6faaefaSjeremylt
157b6faaefaSjeremylt      call ceedqfunctioncreateinterior(ceed,1,diff,&
158b6faaefaSjeremylt     &SOURCE_DIR&
159a05f9790Sjeremylt     &//'t522-operator.h:diff'//char(0),qf_difftet,err)
160b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_difftet,'rho',d*(d+1)/2,ceed_eval_none,err)
161b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_difftet,'u',d,ceed_eval_grad,err)
162b6faaefaSjeremylt      call ceedqfunctionaddoutput(qf_difftet,'v',d,ceed_eval_grad,err)
163b6faaefaSjeremylt
164b6faaefaSjeremylt! -- Operators
165b6faaefaSjeremylt! ---- Setup Tet
166442e7f0bSjeremylt      call ceedoperatorcreate(ceed,qf_setuptet,ceed_qfunction_none,&
167442e7f0bSjeremylt     & ceed_qfunction_none,op_setuptet,err)
16815910d16Sjeremylt      call ceedoperatorsetfield(op_setuptet,'_weight',&
16915910d16Sjeremylt     & ceed_elemrestriction_none,bxtet,ceed_vector_none,err)
170b6faaefaSjeremylt      call ceedoperatorsetfield(op_setuptet,'dx',erestrictxtet,&
171a8d32208Sjeremylt     & bxtet,ceed_vector_active,err)
172b6faaefaSjeremylt      call ceedoperatorsetfield(op_setuptet,'rho',erestrictqditet,&
173a8d32208Sjeremylt     & ceed_basis_collocated,qdatatet,err)
174b6faaefaSjeremylt! ---- diff Tet
175442e7f0bSjeremylt      call ceedoperatorcreate(ceed,qf_difftet,ceed_qfunction_none,&
176442e7f0bSjeremylt     & ceed_qfunction_none,op_difftet,err)
177b6faaefaSjeremylt      call ceedoperatorsetfield(op_difftet,'rho',erestrictqditet,&
178a8d32208Sjeremylt     & ceed_basis_collocated,qdatatet,err)
179b6faaefaSjeremylt      call ceedoperatorsetfield(op_difftet,'u',erestrictutet,&
180a8d32208Sjeremylt     & butet,ceed_vector_active,err)
181b6faaefaSjeremylt      call ceedoperatorsetfield(op_difftet,'v',erestrictutet,&
182a8d32208Sjeremylt     & butet,ceed_vector_active,err)
183b6faaefaSjeremylt
184b6faaefaSjeremylt! Hex Elements
185b6faaefaSjeremylt      do i=0,nelemhex-1
186b6faaefaSjeremylt        col=mod(i,nx)
187b6faaefaSjeremylt        row=i/nx
188b6faaefaSjeremylt        offset=(nxtet*2+1)*(nytet*2)*(1+row)+col*2
189b6faaefaSjeremylt        do j=0,phex-1
190b6faaefaSjeremylt          do k=0,phex-1
191b6faaefaSjeremylt            indxhex(phex*(phex*i+k)+j+1)=offset+k*(nxhex*2+1)+j
192b6faaefaSjeremylt          enddo
193b6faaefaSjeremylt        enddo
194b6faaefaSjeremylt      enddo
195b6faaefaSjeremylt
196b6faaefaSjeremylt! -- Restrictions
197*d979a051Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemhex,phex*phex,d,ndofs,&
198*d979a051Sjeremylt     & d*ndofs,ceed_mem_host,ceed_use_pointer,indxhex,erestrictxhex,err)
199b6faaefaSjeremylt
200*d979a051Sjeremylt      call ceedelemrestrictioncreate(ceed,nelemhex,phex*phex,1,1,ndofs,&
201b6faaefaSjeremylt     & ceed_mem_host,ceed_use_pointer,indxhex,erestrictuhex,err)
2027509a596Sjeremylt      stridesqdhex=[1,qhex*qhex,qhex*qhex*d*(d+1)/2]
2037509a596Sjeremylt      call ceedelemrestrictioncreatestrided(ceed,nelemhex,qhex*qhex,&
204*d979a051Sjeremylt     & d*(d+1)/2,d*(d+1)/2*nqptshex,stridesqdhex,erestrictqdihex,err)
205b6faaefaSjeremylt
206b6faaefaSjeremylt! -- Bases
207b6faaefaSjeremylt      call ceedbasiscreatetensorh1lagrange(ceed,d,d,phex,qhex,ceed_gauss,&
208b6faaefaSjeremylt     & bxhex,err)
209b6faaefaSjeremylt      call ceedbasiscreatetensorh1lagrange(ceed,d,1,phex,qhex,ceed_gauss,&
210b6faaefaSjeremylt     & buhex,err)
211b6faaefaSjeremylt
212b6faaefaSjeremylt! -- QFunctions
213b6faaefaSjeremylt      call ceedqfunctioncreateinterior(ceed,1,setup,&
214b6faaefaSjeremylt     &SOURCE_DIR&
215872c4ebbSjeremylt     &//'t522-operator.h:setup'//char(0),qf_setuphex,err)
216b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_setuphex,'_weight',1,ceed_eval_weight,err)
217b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_setuphex,'dx',d*d,ceed_eval_grad,err)
218b6faaefaSjeremylt      call ceedqfunctionaddoutput(qf_setuphex,'rho',d*(d+1)/2,ceed_eval_none,&
219b6faaefaSjeremylt     & err)
220b6faaefaSjeremylt
221b6faaefaSjeremylt      call ceedqfunctioncreateinterior(ceed,1,diff,&
222b6faaefaSjeremylt     &SOURCE_DIR&
223872c4ebbSjeremylt     &//'t522-operator.h:diff'//char(0),qf_diffhex,err)
224b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_diffhex,'rho',d*(d+1)/2,ceed_eval_none,err)
225b6faaefaSjeremylt      call ceedqfunctionaddinput(qf_diffhex,'u',d,ceed_eval_grad,err)
226b6faaefaSjeremylt      call ceedqfunctionaddoutput(qf_diffhex,'v',d,ceed_eval_grad,err)
227b6faaefaSjeremylt
228b6faaefaSjeremylt! -- Operators
229b6faaefaSjeremylt! ---- Setup Hex
230442e7f0bSjeremylt      call ceedoperatorcreate(ceed,qf_setuphex,ceed_qfunction_none,&
231442e7f0bSjeremylt     & ceed_qfunction_none,op_setuphex,err)
23215910d16Sjeremylt      call ceedoperatorsetfield(op_setuphex,'_weight',&
23315910d16Sjeremylt     & ceed_elemrestriction_none,bxhex,ceed_vector_none,err)
234b6faaefaSjeremylt      call ceedoperatorsetfield(op_setuphex,'dx',erestrictxhex,&
235a8d32208Sjeremylt     & bxhex,ceed_vector_active,err)
236b6faaefaSjeremylt      call ceedoperatorsetfield(op_setuphex,'rho',erestrictqdihex,&
237a8d32208Sjeremylt     & ceed_basis_collocated,qdatahex,err)
238b6faaefaSjeremylt! ---- diff Hex
239442e7f0bSjeremylt      call ceedoperatorcreate(ceed,qf_diffhex,ceed_qfunction_none,&
240442e7f0bSjeremylt     & ceed_qfunction_none,op_diffhex,err)
241b6faaefaSjeremylt      call ceedoperatorsetfield(op_diffhex,'rho',erestrictqdihex,&
242a8d32208Sjeremylt     & ceed_basis_collocated,qdatahex,err)
243b6faaefaSjeremylt      call ceedoperatorsetfield(op_diffhex,'u',erestrictuhex,&
244a8d32208Sjeremylt     & buhex,ceed_vector_active,err)
245b6faaefaSjeremylt      call ceedoperatorsetfield(op_diffhex,'v',erestrictuhex,&
246a8d32208Sjeremylt     & buhex,ceed_vector_active,err)
247b6faaefaSjeremylt
248b6faaefaSjeremylt! Composite Operators
249b6faaefaSjeremylt      call ceedcompositeoperatorcreate(ceed,op_setup,err)
250b6faaefaSjeremylt      call ceedcompositeoperatoraddsub(op_setup,op_setuptet,err)
251b6faaefaSjeremylt      call ceedcompositeoperatoraddsub(op_setup,op_setuphex,err)
252b6faaefaSjeremylt
253b6faaefaSjeremylt      call ceedcompositeoperatorcreate(ceed,op_diff,err)
254b6faaefaSjeremylt      call ceedcompositeoperatoraddsub(op_diff,op_difftet,err)
255b6faaefaSjeremylt      call ceedcompositeoperatoraddsub(op_diff,op_diffhex,err)
256b6faaefaSjeremylt
257b6faaefaSjeremylt! Apply Setup Operator
258e97ff134Sjeremylt      call ceedoperatorapply(op_setup,x,ceed_vector_none,&
259e97ff134Sjeremylt     & ceed_request_immediate,err)
260b6faaefaSjeremylt
261b6faaefaSjeremylt! Apply diff Operator
262b6faaefaSjeremylt      call ceedvectorcreate(ceed,ndofs,u,err)
263b6faaefaSjeremylt      call ceedvectorsetvalue(u,1.d0,err)
264b6faaefaSjeremylt      call ceedvectorcreate(ceed,ndofs,v,err)
265b6faaefaSjeremylt
266b6faaefaSjeremylt      call ceedoperatorapply(op_diff,u,v,ceed_request_immediate,err)
267b6faaefaSjeremylt
268b6faaefaSjeremylt! Check Output
269b6faaefaSjeremylt      call ceedvectorgetarrayread(v,ceed_mem_host,hv,voffset,err)
270b6faaefaSjeremylt      do i=1,ndofs
271b6faaefaSjeremylt      if (abs(hv(voffset+i))>1.0d-14) then
272b6faaefaSjeremylt! LCOV_EXCL_START
273b6faaefaSjeremylt        write(*,*) 'Computed: ',total,' != True: 0.0'
274b6faaefaSjeremylt! LCOV_EXCL_STOP
275b6faaefaSjeremylt      endif
276b6faaefaSjeremylt      enddo
277b6faaefaSjeremylt      call ceedvectorrestorearrayread(v,hv,voffset,err)
278b6faaefaSjeremylt
279b6faaefaSjeremylt! Cleanup
280b6faaefaSjeremylt      call ceedqfunctiondestroy(qf_setuptet,err)
281b6faaefaSjeremylt      call ceedqfunctiondestroy(qf_difftet,err)
282b6faaefaSjeremylt      call ceedoperatordestroy(op_setuptet,err)
283b6faaefaSjeremylt      call ceedoperatordestroy(op_difftet,err)
284b6faaefaSjeremylt      call ceedqfunctiondestroy(qf_setuphex,err)
285b6faaefaSjeremylt      call ceedqfunctiondestroy(qf_diffhex,err)
286b6faaefaSjeremylt      call ceedoperatordestroy(op_setuphex,err)
287b6faaefaSjeremylt      call ceedoperatordestroy(op_diffhex,err)
288b6faaefaSjeremylt      call ceedoperatordestroy(op_setup,err)
289b6faaefaSjeremylt      call ceedoperatordestroy(op_diff,err)
290b6faaefaSjeremylt      call ceedelemrestrictiondestroy(erestrictutet,err)
291b6faaefaSjeremylt      call ceedelemrestrictiondestroy(erestrictxtet,err)
292b6faaefaSjeremylt      call ceedelemrestrictiondestroy(erestrictqditet,err)
293b6faaefaSjeremylt      call ceedelemrestrictiondestroy(erestrictuhex,err)
294b6faaefaSjeremylt      call ceedelemrestrictiondestroy(erestrictxhex,err)
295b6faaefaSjeremylt      call ceedelemrestrictiondestroy(erestrictqdihex,err)
296b6faaefaSjeremylt      call ceedbasisdestroy(butet,err)
297b6faaefaSjeremylt      call ceedbasisdestroy(bxtet,err)
298b6faaefaSjeremylt      call ceedbasisdestroy(buhex,err)
299b6faaefaSjeremylt      call ceedbasisdestroy(bxhex,err)
300b6faaefaSjeremylt      call ceedvectordestroy(x,err)
301b6faaefaSjeremylt      call ceedvectordestroy(u,err)
302b6faaefaSjeremylt      call ceedvectordestroy(v,err)
303b6faaefaSjeremylt      call ceedvectordestroy(qdatatet,err)
304b6faaefaSjeremylt      call ceedvectordestroy(qdatahex,err)
305b6faaefaSjeremylt      call ceeddestroy(ceed,err)
306b6faaefaSjeremylt      end
307b6faaefaSjeremylt!-----------------------------------------------------------------------
308