/[escript]/trunk/escript/test/python/test_pdetools.py
ViewVC logotype

Annotation of /trunk/escript/test/python/test_pdetools.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1072 - (hide annotations)
Thu Mar 29 06:44:30 2007 UTC (14 years, 7 months ago) by gross
File MIME type: text/x-python
File size: 17529 byte(s)
PDE assemblage for reduced integration order + tests added.


1 gross 525 # $Id$
2    
3     """
4     Test suite for the pdetools module
5    
6     The tests must be linked with a Domain class object in the setUp method:
7    
8     from esys.finley import Rectangle
9     class Test_LinearPDEOnFinley(Test_LinearPDE):
10 gross 798 RES_TOL=1-8
11 gross 525 def setUp(self):
12     self.domain = Rectangle(10,10,2)
13 gross 798 def tearDown(self):
14     del self.domain
15 gross 525 suite = unittest.TestSuite()
16     suite.addTest(unittest.makeSuite(Test_LinearPDEOnFinley))
17     unittest.TextTestRunner(verbosity=2).run(suite)
18    
19 gross 637 @var __author__: name of author
20     @var __copyright__: copyrights
21     @var __license__: licence agreement
22     @var __url__: url entry point on documentation
23     @var __version__: version
24     @var __date__: date of the version
25 gross 525 """
26    
27     __author__="Lutz Gross, l.gross@uq.edu.au"
28 elspeth 609 __copyright__=""" Copyright (c) 2006 by ACcESS MNRF
29     http://www.access.edu.au
30     Primary Business: Queensland, Australia"""
31 elspeth 614 __license__="""Licensed under the Open Software License version 3.0
32     http://www.opensource.org/licenses/osl-3.0.php"""
33 gross 525 __url__="http://www.iservo.edu.au/esys/escript"
34     __version__="$Revision$"
35     __date__="$Date$"
36    
37     import unittest
38     from esys.escript import *
39     from esys.escript.pdetools import Locator,Projector,TimeIntegrationManager,NoPDE
40    
41 gross 855 class Test_pdetools_noLumping(unittest.TestCase):
42 gross 525 DEBUG=False
43     VERBOSE=False
44     def test_TimeIntegrationManager_scalar(self):
45     t=0.
46     dt=0.1
47     tm=TimeIntegrationManager(0.,p=1)
48     while t<1.:
49     t+=dt
50     tm.checkin(dt,t)
51     v_guess=tm.extrapolate(dt)
52 gross 798 self.failUnless(abs(v_guess-(tm.getTime()+dt))<self.RES_TOL,"extrapolation is wrong")
53 gross 525
54     def test_TimeIntegrationManager_vector(self):
55     t=0.
56     dt=0.3
57     tm=TimeIntegrationManager(0.,0.,p=1)
58     while t<1.:
59     t+=dt
60     tm.checkin(dt,t,3*t)
61     v_guess=tm.extrapolate(dt)
62     e=max(abs(v_guess[0]-(tm.getTime()+dt)),abs(v_guess[1]-(tm.getTime()+dt)*3.))
63 gross 798 self.failUnless(e<self.RES_TOL,"extrapolation is wrong")
64 gross 525
65     def test_Locator(self):
66     x=self.domain.getX()
67     l=Locator(self.domain,numarray.ones((self.domain.getDim(),)))
68     self.failUnless(ContinuousFunction(self.domain)==l.getFunctionSpace(),"wrong function space from domain")
69    
70     l=Locator(ContinuousFunction(self.domain),numarray.ones((self.domain.getDim(),)))
71     self.failUnless(ContinuousFunction(self.domain)==l.getFunctionSpace(),"wrong function space")
72    
73     xx=l.getX()
74     self.failUnless(isinstance(xx,numarray.NumArray),"wrong vector type")
75 gross 798 self.failUnless(Lsup(xx-numarray.ones((self.domain.getDim(),)))<self.RES_TOL,"location wrong")
76 gross 525 xx=l(x)
77     self.failUnless(isinstance(xx,numarray.NumArray),"wrong vector type")
78 gross 798 self.failUnless(Lsup(xx-numarray.ones((self.domain.getDim(),)))<self.RES_TOL,"value wrong vector")
79 gross 525 xx=l(x[0]+x[1])
80     self.failUnless(isinstance(xx,float),"wrong scalar type")
81 gross 798 self.failUnless(abs(xx-2.)<self.RES_TOL,"value wrong scalar")
82 gross 880
83     def test_Locator_withList(self):
84     x=self.domain.getX()
85     arg=[numarray.ones((self.domain.getDim(),)), numarray.zeros((self.domain.getDim(),))]
86     l=Locator(self.domain,arg)
87     self.failUnless(ContinuousFunction(self.domain)==l.getFunctionSpace(),"wrong function space from domain")
88    
89     l=Locator(ContinuousFunction(self.domain),arg)
90     self.failUnless(ContinuousFunction(self.domain)==l.getFunctionSpace(),"wrong function space")
91    
92     xx=l.getX()
93     self.failUnless(isinstance(xx,list),"list expected")
94     for i in range(len(xx)):
95     self.failUnless(isinstance(xx[i],numarray.NumArray),"vector expected for %s item"%i)
96     self.failUnless(Lsup(xx[i]-arg[i])<self.RES_TOL,"%s-th location is wrong"%i)
97     xx=l(x)
98     self.failUnless(isinstance(xx,list),"list expected (2)")
99     for i in range(len(xx)):
100     self.failUnless(isinstance(xx[i],numarray.NumArray),"vector expected for %s item (2)"%i)
101     self.failUnless(Lsup(xx[i]-arg[i])<self.RES_TOL,"%s-th location is wrong (2)"%i)
102     xx=l(x[0]+x[1])
103     self.failUnless(isinstance(xx,list),"list expected (3)")
104     for i in range(len(xx)):
105     self.failUnless(isinstance(xx[i],float),"wrong scalar type")
106     self.failUnless(abs(xx[i]-(arg[i][0]+arg[i][1]))<self.RES_TOL,"value wrong scalar")
107 gross 525
108     def testProjector_rank0(self):
109     x=ContinuousFunction(self.domain).getX()
110     p=Projector(self.domain,reduce=False,fast=False)
111     td_ref=x[0]
112     td=p(td_ref.interpolate(Function(self.domain)))
113 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
114 gross 525
115     def testProjector_rank1(self):
116     x=ContinuousFunction(self.domain).getX()
117     p=Projector(self.domain,reduce=False,fast=False)
118     td_ref=x
119     td=p(td_ref.interpolate(Function(self.domain)))
120 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
121 gross 525
122     def testProjector_rank2(self):
123     x=ContinuousFunction(self.domain).getX()
124     p=Projector(self.domain,reduce=False,fast=False)
125     td_ref=[[11.,12.],[21,22.]]*(x[0]+x[1])
126     td=p(td_ref.interpolate(Function(self.domain)))
127 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
128 gross 525
129     def testProjector_rank3(self):
130     x=ContinuousFunction(self.domain).getX()
131     p=Projector(self.domain,reduce=False,fast=False)
132     td_ref=[[[111.,112.],[121,122.]],[[211.,212.],[221,222.]]]*(x[0]+x[1])
133     td=p(td_ref.interpolate(Function(self.domain)))
134 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
135 gross 525
136     def testProjector_rank4(self):
137     x=ContinuousFunction(self.domain).getX()
138     p=Projector(self.domain,reduce=False,fast=False)
139     td_ref=[[[[1111.,1112.],[1121,1122.]],[[1211.,1212.],[1221,1222.]]],[[[2111.,2112.],[2121,2122.]],[[2211.,2212.],[2221,2222.]]]]*(x[0]+x[1])
140     td=p(td_ref.interpolate(Function(self.domain)))
141 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
142 gross 525
143    
144     def testProjector_rank0_reduced(self):
145     x=ContinuousFunction(self.domain).getX()
146     p=Projector(self.domain,reduce=True,fast=False)
147     td_ref=x[0]
148     td=p(td_ref.interpolate(Function(self.domain)))
149 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
150 gross 525
151     def testProjector_rank1_reduced(self):
152     x=ContinuousFunction(self.domain).getX()
153     p=Projector(self.domain,reduce=True,fast=False)
154     td_ref=x
155     td=p(td_ref.interpolate(Function(self.domain)))
156 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
157 gross 525
158     def testProjector_rank2_reduced(self):
159     x=ContinuousFunction(self.domain).getX()
160     p=Projector(self.domain,reduce=True,fast=False)
161     td_ref=[[11.,12.],[21,22.]]*(x[0]+x[1])
162     td=p(td_ref.interpolate(Function(self.domain)))
163 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
164 gross 525
165     def testProjector_rank3_reduced(self):
166     x=ContinuousFunction(self.domain).getX()
167     p=Projector(self.domain,reduce=True,fast=False)
168     td_ref=[[[111.,112.],[121,122.]],[[211.,212.],[221,222.]]]*(x[0]+x[1])
169     td=p(td_ref.interpolate(Function(self.domain)))
170 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
171 gross 525
172     def testProjector_rank4_reduced(self):
173     x=ContinuousFunction(self.domain).getX()
174     p=Projector(self.domain,reduce=True,fast=False)
175     td_ref=[[[[1111.,1112.],[1121,1122.]],[[1211.,1212.],[1221,1222.]]],[[[2111.,2112.],[2121,2122.]],[[2211.,2212.],[2221,2222.]]]]*(x[0]+x[1])
176     td=p(td_ref.interpolate(Function(self.domain)))
177 gross 798 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
178 gross 525
179 gross 1072 def testProjector_rank0_with_reduced_input(self):
180 gross 525 x=ContinuousFunction(self.domain).getX()
181 gross 1072 p=Projector(self.domain,reduce=False,fast=False)
182 gross 525 td_ref=x[0]
183     td=p(td_ref.interpolate(Function(self.domain)))
184 gross 1072 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
185 gross 525
186 gross 1072 def testProjector_rank1_with_reduced_input(self):
187 gross 525 x=ContinuousFunction(self.domain).getX()
188 gross 1072 p=Projector(self.domain,reduce=False,fast=False)
189 gross 525 td_ref=x
190     td=p(td_ref.interpolate(Function(self.domain)))
191 gross 1072 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
192 gross 525
193 gross 1072 def testProjector_rank2_with_reduced_input(self):
194 gross 525 x=ContinuousFunction(self.domain).getX()
195 gross 1072 p=Projector(self.domain,reduce=False,fast=False)
196 gross 525 td_ref=[[11.,12.],[21,22.]]*(x[0]+x[1])
197     td=p(td_ref.interpolate(Function(self.domain)))
198 gross 1072 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
199 gross 525
200 gross 1072 def testProjector_rank3_with_reduced_input(self):
201 gross 525 x=ContinuousFunction(self.domain).getX()
202 gross 1072 p=Projector(self.domain,reduce=False,fast=False)
203 gross 525 td_ref=[[[111.,112.],[121,122.]],[[211.,212.],[221,222.]]]*(x[0]+x[1])
204     td=p(td_ref.interpolate(Function(self.domain)))
205 gross 1072 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
206 gross 525
207 gross 1072 def testProjector_rank4_with_reduced_input(self):
208 gross 525 x=ContinuousFunction(self.domain).getX()
209 gross 1072 p=Projector(self.domain,reduce=False,fast=False)
210 gross 525 td_ref=[[[[1111.,1112.],[1121,1122.]],[[1211.,1212.],[1221,1222.]]],[[[2111.,2112.],[2121,2122.]],[[2211.,2212.],[2221,2222.]]]]*(x[0]+x[1])
211     td=p(td_ref.interpolate(Function(self.domain)))
212 gross 1072 self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
213 gross 525
214 gross 1072
215     def testProjector_rank0_reduced_with_reduced_input(self):
216     x=ContinuousFunction(self.domain).getX()
217     p=Projector(self.domain,reduce=True,fast=False)
218     td_ref=1.
219     td=p(Data(td_ref,ReducedFunction(self.domain)))
220     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
221    
222     def testProjector_rank1_reduced_with_reduced_input(self):
223     x=ContinuousFunction(self.domain).getX()
224     p=Projector(self.domain,reduce=True,fast=False)
225     td_ref=numarray.array([1.,2.,3.])
226     td=p(Data(td_ref,ReducedFunction(self.domain)))
227     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
228    
229     def testProjector_rank2_reduced_with_reduced_input(self):
230     x=ContinuousFunction(self.domain).getX()
231     p=Projector(self.domain,reduce=True,fast=False)
232     td_ref=numarray.array([[11.,12.],[21,22.]])
233     td=p(Data(td_ref,ReducedFunction(self.domain)))
234     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
235    
236     def testProjector_rank3_reduced_with_reduced_input(self):
237     x=ContinuousFunction(self.domain).getX()
238     p=Projector(self.domain,reduce=True,fast=False)
239     td_ref=numarray.array([[[111.,112.],[121,122.]],[[211.,212.],[221,222.]]])
240     td=p(Data(td_ref,ReducedFunction(self.domain)))
241     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
242    
243     def testProjector_rank4_reduced_with_reduced_input(self):
244     x=ContinuousFunction(self.domain).getX()
245     p=Projector(self.domain,reduce=True,fast=False)
246     td_ref=numarray.array([[[[1111.,1112.],[1121,1122.]],[[1211.,1212.],[1221,1222.]]],[[[2111.,2112.],[2121,2122.]],[[2211.,2212.],[2221,2222.]]]])
247     td=p(Data(td_ref,ReducedFunction(self.domain)))
248     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*self.RES_TOL,"value wrong")
249    
250    
251 gross 525 def test_NoPDE_scalar_missing_r(self):
252     p=NoPDE(self.domain)
253     x=self.domain.getX()
254     msk=whereZero(x[0])
255     p.setValue(D=1.,Y=1.,q=msk)
256     u=p.getSolution()
257     u_ex=(1.-msk)
258 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
259 gross 525
260     def test_NoPDE_scalar_missing_Y(self):
261     p=NoPDE(self.domain)
262     x=self.domain.getX()
263     msk=whereZero(x[0])
264     p.setValue(D=1.,q=msk,r=2.)
265     u=p.getSolution()
266     u_ex=msk*2.
267 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
268 gross 525
269     def test_NoPDE_scalar_constant(self):
270     p=NoPDE(self.domain)
271     x=self.domain.getX()
272     msk=whereZero(x[0])
273     p.setValue(D=1.,Y=1.,q=msk,r=2.)
274     u=p.getSolution()
275     u_ex=(1.-msk)+msk*2.
276 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
277 gross 525
278     def test_NoPDE_scalar_variable(self):
279     p=NoPDE(self.domain)
280     x=self.domain.getX()
281     msk=whereZero(x[0])
282     p.setValue(D=x[0],Y=2*x[0],q=msk,r=2.)
283     u=p.getSolution()
284     u_ex=2.
285 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
286 gross 525
287     def test_NoPDE_vector_missing_Y(self):
288     p=NoPDE(self.domain)
289     x=self.domain.getX()
290     msk=whereZero(x[0])*[1.,0.]
291 gross 854 p.setValue(D=numarray.ones([2]),q=msk,r=2.)
292 gross 525 u=p.getSolution()
293     u_ex=msk*2.
294 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
295 gross 525
296     def test_NoPDE_vector_missing_r(self):
297     p=NoPDE(self.domain)
298     x=self.domain.getX()
299     msk=whereZero(x[0])*[1.,0.]
300 gross 854 p.setValue(D=numarray.ones([2]),Y=numarray.ones([2]),q=msk)
301 gross 525 u=p.getSolution()
302     u_ex=(1.-msk)
303 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
304 gross 525
305     def test_NoPDE_vector_constant(self):
306     p=NoPDE(self.domain)
307     x=self.domain.getX()
308     msk=whereZero(x[0])*[1.,0.]
309 gross 854 p.setValue(D=numarray.ones([2]),Y=numarray.ones([2]),q=msk,r=2.)
310 gross 525 u=p.getSolution()
311     u_ex=(1.-msk)+msk*2.
312 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
313 gross 525
314     def test_NoPDE_vector_variable(self):
315     p=NoPDE(self.domain)
316     x=self.domain.getX()
317     msk=whereZero(x[0])*[1.,0.]
318     p.setValue(D=x[:2],Y=2*x[:2],q=msk,r=2.)
319     u=p.getSolution()
320     u_ex=2.
321 gross 798 self.failUnless(Lsup(u_ex-u)<Lsup(u_ex)*self.RES_TOL,"value wrong")
322 gross 855
323    
324     class Test_pdetools(Test_pdetools_noLumping):
325 gross 1072 def testProjector_rank0_fast_reduced(self):
326 gross 855 x=ContinuousFunction(self.domain).getX()
327     h=Lsup(self.domain.getSize())
328 gross 1072 p=Projector(self.domain,reduce=True,fast=True)
329 gross 855 td_ref=x[0]
330     td=p(td_ref.interpolate(Function(self.domain)))
331     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
332    
333 gross 1072 def testProjector_rank1_fast_reduced(self):
334 gross 855 x=ContinuousFunction(self.domain).getX()
335     h=Lsup(self.domain.getSize())
336 gross 1072 p=Projector(self.domain,reduce=True,fast=True)
337 gross 855 td_ref=x
338     td=p(td_ref.interpolate(Function(self.domain)))
339     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
340    
341 gross 1072 def testProjector_rank2_fast_reduced(self):
342 gross 855 x=ContinuousFunction(self.domain).getX()
343     h=Lsup(self.domain.getSize())
344 gross 1072 p=Projector(self.domain,reduce=True,fast=True)
345 gross 855 td_ref=[[11.,12.],[21,22.]]*(x[0]+x[1])
346     td=p(td_ref.interpolate(Function(self.domain)))
347     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
348    
349 gross 1072 def testProjector_rank3_fast_reduced(self):
350 gross 855 x=ContinuousFunction(self.domain).getX()
351     h=Lsup(self.domain.getSize())
352 gross 1072 p=Projector(self.domain,reduce=True,fast=True)
353 gross 855 td_ref=[[[111.,112.],[121,122.]],[[211.,212.],[221,222.]]]*(x[0]+x[1])
354     td=p(td_ref.interpolate(Function(self.domain)))
355     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
356    
357 gross 1072 def testProjector_rank4_fast_reduced(self):
358 gross 855 x=ContinuousFunction(self.domain).getX()
359     h=Lsup(self.domain.getSize())
360 gross 1072 p=Projector(self.domain,reduce=True,fast=True)
361 gross 855 td_ref=[[[[1111.,1112.],[1121,1122.]],[[1211.,1212.],[1221,1222.]]],[[[2111.,2112.],[2121,2122.]],[[2211.,2212.],[2221,2222.]]]]*(x[0]+x[1])
362     td=p(td_ref.interpolate(Function(self.domain)))
363     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
364 gross 1072
365     def testProjector_rank0_fast_reduced_with_reduced_input(self):
366     x=ContinuousFunction(self.domain).getX()
367     h=Lsup(self.domain.getSize())
368     p=Projector(self.domain,reduce=True,fast=True)
369     td_ref=1.
370     td=p(Data(td_ref,ReducedFunction(self.domain)))
371     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
372    
373     def testProjector_rank1_fast_reduced_with_reduced_input(self):
374     x=ContinuousFunction(self.domain).getX()
375     h=Lsup(self.domain.getSize())
376     p=Projector(self.domain,reduce=True,fast=True)
377     td_ref=numarray.array([1.,2.,3.])
378     td=p(Data(td_ref,ReducedFunction(self.domain)))
379     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
380    
381     def testProjector_rank2_fast_reduced_with_reduced_input(self):
382     x=ContinuousFunction(self.domain).getX()
383     h=Lsup(self.domain.getSize())
384     p=Projector(self.domain,reduce=True,fast=True)
385     td_ref=numarray.array([[11.,12.],[21,22.]])
386     td=p(Data(td_ref,ReducedFunction(self.domain)))
387     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
388    
389     def testProjector_rank3_fast_reduced_with_reduced_input(self):
390     x=ContinuousFunction(self.domain).getX()
391     h=Lsup(self.domain.getSize())
392     p=Projector(self.domain,reduce=True,fast=True)
393     td_ref=numarray.array([[[111.,112.],[121,122.]],[[211.,212.],[221,222.]]])
394     td=p(Data(td_ref,ReducedFunction(self.domain)))
395     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
396    
397     def testProjector_rank4_fast_reduced_with_reduced_input(self):
398     x=ContinuousFunction(self.domain).getX()
399     h=Lsup(self.domain.getSize())
400     p=Projector(self.domain,reduce=True,fast=True)
401     td_ref=numarray.array([[[[1111.,1112.],[1121,1122.]],[[1211.,1212.],[1221,1222.]]],[[[2111.,2112.],[2121,2122.]],[[2211.,2212.],[2221,2222.]]]])
402     td=p(Data(td_ref,ReducedFunction(self.domain)))
403     self.failUnless(Lsup(td-td_ref)<Lsup(td_ref)*h,"value wrong")
404    

  ViewVC Help
Powered by ViewVC 1.1.26