/[escript]/trunk/finley/src/CPPAdapter/MeshAdapter.h
ViewVC logotype

Annotation of /trunk/finley/src/CPPAdapter/MeshAdapter.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2642 - (hide annotations)
Tue Sep 1 04:15:50 2009 UTC (9 years, 4 months ago) by jfenwick
File MIME type: text/plain
File size: 18673 byte(s)
pre cleanup
1 ksteube 1312
2     /*******************************************************
3 ksteube 1811 *
4 jfenwick 2548 * Copyright (c) 2003-2009 by University of Queensland
5 ksteube 1811 * Earth Systems Science Computational Center (ESSCC)
6     * http://www.uq.edu.au/esscc
7     *
8     * Primary Business: Queensland, Australia
9     * Licensed under the Open Software License version 3.0
10     * http://www.opensource.org/licenses/osl-3.0.php
11     *
12     *******************************************************/
13 ksteube 1312
14 ksteube 1811
15 jgs 149 #if !defined finley_MeshAdapter_20040526_H
16 jgs 82 #define finley_MeshAdapter_20040526_H
17 woo409 757 #include "system_dep.h"
18 jgs 82
19     extern "C" {
20 robwdcock 682 #include "../Mesh.h"
21     #include "../Finley.h"
22     #include "../Assemble.h"
23     #include "paso/SystemMatrix.h"
24 gross 1366 #include "paso/SolverFCT.h"
25 ksteube 1800 #include "paso/Paso_MPI.h"
26 jgs 82 }
27 jgs 472
28     #include "FinleyError.h"
29     #include "FinleyAdapterException.h"
30 jgs 149
31 jgs 480 #include "SystemMatrixAdapter.h"
32 gross 1366 #include "TransportProblemAdapter.h"
33 robwdcock 682 #include "escript/AbstractContinuousDomain.h"
34     #include "escript/FunctionSpace.h"
35     #include "escript/FunctionSpaceFactory.h"
36 jgs 472
37 jgs 82 #include <boost/shared_ptr.hpp>
38 jgs 153 #include <boost/python/dict.hpp>
39 jgs 472 #include <boost/python/extract.hpp>
40    
41 jgs 82 #include <map>
42     #include <vector>
43     #include <string>
44 jgs 472 #include <sstream>
45 jgs 82
46 jgs 480 //
47     // forward declarations
48     class Data;
49    
50     //using namespace escript;
51    
52 jgs 82 namespace finley {
53    
54 jgs 123 struct null_deleter
55     {
56     void operator()(void const *ptr) const
57     {
58     }
59     };
60    
61    
62 jgs 82 /**
63     \brief
64     MeshAdapter implements the AbstractContinuousDomain
65     interface for the Finley library.
66    
67     Description:
68     MeshAdapter implements the AbstractContinuousDomain
69     interface for the Finley library.
70     */
71    
72 jgs 480 class MeshAdapter : public escript::AbstractContinuousDomain {
73 jgs 82
74     public:
75    
76     //
77     // Codes for function space types supported
78     static const int DegreesOfFreedom;
79     static const int ReducedDegreesOfFreedom;
80     static const int Nodes;
81 gross 1062 static const int ReducedNodes;
82 jgs 82 static const int Elements;
83 gross 1059 static const int ReducedElements;
84 jgs 82 static const int FaceElements;
85 gross 1059 static const int ReducedFaceElements;
86 jgs 82 static const int Points;
87     static const int ContactElementsZero;
88 gross 1059 static const int ReducedContactElementsZero;
89 jgs 82 static const int ContactElementsOne;
90 gross 1059 static const int ReducedContactElementsOne;
91 jgs 82
92     /**
93     \brief
94     Constructor for MeshAdapter
95    
96     Description:
97     Constructor for MeshAdapter. The pointer passed to MeshAdapter
98 ksteube 1312 is deleted using a call to Finley_Mesh_free in the
99 jgs 82 MeshAdapter destructor.
100    
101     Throws:
102     May throw an exception derived from EsysException
103    
104     \param finleyMesh Input - A pointer to the externally constructed
105     finley mesh.The pointer passed to MeshAdapter
106     is deleted using a call to
107 ksteube 1312 Finley_Mesh_free in the MeshAdapter
108 jgs 82 destructor.
109     */
110 woo409 757 FINLEY_DLL_API
111 jgs 82 MeshAdapter(Finley_Mesh* finleyMesh=0);
112 jgs 149
113 jgs 82 /**
114     \brief
115     Copy constructor.
116     */
117 woo409 757 FINLEY_DLL_API
118 jgs 82 MeshAdapter(const MeshAdapter& in);
119 jgs 149
120 jgs 82 /**
121     \brief
122     Destructor for MeshAdapter. As specified in the constructor
123 ksteube 1312 this calls Finley_Mesh_free for the pointer given to the
124 jgs 82 constructor.
125     */
126 woo409 757 FINLEY_DLL_API
127 jgs 82 ~MeshAdapter();
128 jgs 149
129 jgs 82 /**
130     \brief
131 ksteube 1312 return the number of processors used for this domain
132     */
133     FINLEY_DLL_API
134     virtual int getMPISize() const;
135     /**
136     \brief
137     return the number MPI rank of this processor
138     */
139    
140     FINLEY_DLL_API
141     virtual int getMPIRank() const;
142    
143     /**
144     \brief
145 ksteube 1877 If compiled for MPI then execute an MPI_Barrier, else do nothing
146     */
147    
148     FINLEY_DLL_API
149     virtual void MPIBarrier() const;
150    
151     /**
152     \brief
153     Return true if on MPI processor 0, else false
154     */
155    
156     FINLEY_DLL_API
157     virtual bool onMasterProcessor() const;
158    
159 jfenwick 2640 FINLEY_DLL_API
160     #ifdef PASO_MPI
161     MPI_Comm
162     #else
163     unsigned int
164     #endif
165     getMPIComm() const;
166    
167 ksteube 1877 /**
168     \brief
169 jgs 82 return this as an AbstractContinuousDomain.
170     */
171     inline const AbstractContinuousDomain& asAbstractContinuousDomain() const
172     {
173     return *(static_cast<const AbstractContinuousDomain*>(this));
174     }
175    
176     /**
177     \brief
178     return this as an AbstractDomain.
179     */
180     inline const AbstractDomain& asAbstractDomain() const
181     {
182     return *(static_cast<const AbstractDomain*>(this));
183     }
184 jgs 149
185 jgs 82 /**
186     \brief
187     Write the current mesh to a file with the given name.
188     \param fileName Input - The name of the file to write to.
189     */
190 woo409 757 FINLEY_DLL_API
191 jgs 82 void write(const std::string& fileName) const;
192 jgs 149
193 jgs 82 /**
194     \brief
195 jfenwick 2519 \param full
196 ksteube 1326 */
197     FINLEY_DLL_API
198 jfenwick 2519 void Print_Mesh_Info(const bool full=false) const;
199 ksteube 1326
200     /**
201     \brief
202 ksteube 1312 dumps the mesh to a file with the given name.
203     \param fileName Input - The name of the file
204     */
205     FINLEY_DLL_API
206     void dump(const std::string& fileName) const;
207    
208     /**
209     \brief
210 jgs 149 return the pointer to the underlying finley mesh structure
211 jgs 82 */
212 woo409 757 FINLEY_DLL_API
213 jgs 82 Finley_Mesh* getFinley_Mesh() const;
214 jgs 149
215 jgs 110 /**
216     \brief
217     Return the tag key for the given sample number.
218     \param functionSpaceType Input - The function space type.
219     \param sampleNo Input - The sample number.
220     */
221 woo409 757 FINLEY_DLL_API
222 jgs 110 int getTagFromSampleNo(int functionSpaceType, int sampleNo) const;
223 jgs 149
224 jgs 110 /**
225     \brief
226     Return the reference number of the given sample number.
227     \param functionSpaceType Input - The function space type.
228     */
229 woo409 757 FINLEY_DLL_API
230 jfenwick 2487 const int* borrowSampleReferenceIDs(int functionSpaceType) const;
231 jgs 110
232     /**
233     \brief
234 jgs 82 Returns true if the given integer is a valid function space type
235     for this domain.
236     */
237 woo409 757 FINLEY_DLL_API
238 jgs 82 virtual bool isValidFunctionSpaceType(int functionSpaceType) const;
239 jgs 149
240 jgs 82 /**
241     \brief
242     Return a description for this domain
243     */
244 woo409 757 FINLEY_DLL_API
245 jgs 82 virtual std::string getDescription() const;
246 jgs 149
247 jgs 82 /**
248     \brief
249     Return a description for the given function space type code
250     */
251 woo409 757 FINLEY_DLL_API
252 jgs 82 virtual std::string functionSpaceTypeAsString(int functionSpaceType) const;
253 jgs 110
254 jgs 82 /**
255     \brief
256     Build the table of function space type names
257     */
258 woo409 757 FINLEY_DLL_API
259 jgs 82 void setFunctionSpaceTypeNames();
260 jgs 149
261 jgs 82 /**
262     \brief
263     Return a continuous FunctionSpace code
264     */
265 woo409 757 FINLEY_DLL_API
266 jgs 82 virtual int getContinuousFunctionCode() const;
267 jgs 149
268 jgs 82 /**
269     \brief
270 gross 1062 Return a continuous on reduced order nodes FunctionSpace code
271     */
272     FINLEY_DLL_API
273     virtual int getReducedContinuousFunctionCode() const;
274    
275     /**
276     \brief
277 gross 1059 Return a function FunctionSpace code
278 jgs 82 */
279 woo409 757 FINLEY_DLL_API
280 jgs 82 virtual int getFunctionCode() const;
281 jgs 149
282 jgs 82 /**
283     \brief
284 gross 1059 Return a function with reduced integration order FunctionSpace code
285     */
286     FINLEY_DLL_API
287     virtual int getReducedFunctionCode() const;
288    
289     /**
290     \brief
291 jgs 82 Return a function on boundary FunctionSpace code
292     */
293 woo409 757 FINLEY_DLL_API
294 jgs 82 virtual int getFunctionOnBoundaryCode() const;
295 jgs 149
296 jgs 82 /**
297     \brief
298 gross 1059 Return a function on boundary with reduced integration order FunctionSpace code
299     */
300     FINLEY_DLL_API
301     virtual int getReducedFunctionOnBoundaryCode() const;
302    
303     /**
304     \brief
305 jgs 82 Return a FunctionOnContactZero code
306     */
307 woo409 757 FINLEY_DLL_API
308 jgs 82 virtual int getFunctionOnContactZeroCode() const;
309 jgs 149
310 jgs 82 /**
311     \brief
312 gross 1059 Return a FunctionOnContactZero code with reduced integration order
313     */
314     FINLEY_DLL_API
315     virtual int getReducedFunctionOnContactZeroCode() const;
316    
317     /**
318     \brief
319 jgs 82 Return a FunctionOnContactOne code
320     */
321 woo409 757 FINLEY_DLL_API
322 jgs 82 virtual int getFunctionOnContactOneCode() const;
323 jgs 149
324 jgs 82 /**
325     \brief
326 gross 1059 Return a FunctionOnContactOne code with reduced integration order
327     */
328     FINLEY_DLL_API
329     virtual int getReducedFunctionOnContactOneCode() const;
330    
331     /**
332     \brief
333 jgs 82 Return a Solution code
334     */
335 woo409 757 FINLEY_DLL_API
336 jgs 82 virtual int getSolutionCode() const;
337 jgs 149
338 jgs 82 /**
339     \brief
340     Return a ReducedSolution code
341     */
342 woo409 757 FINLEY_DLL_API
343 jgs 82 virtual int getReducedSolutionCode() const;
344 jgs 149
345 jgs 82 /**
346     \brief
347     Return a DiracDeltaFunction code
348     */
349 woo409 757 FINLEY_DLL_API
350 jgs 82 virtual int getDiracDeltaFunctionCode() const;
351 jgs 149
352     /**
353 bcumming 782 5B
354 jgs 149 \brief
355     */
356 jgs 82 typedef std::map<int, std::string> FunctionSpaceNamesMapType;
357 jgs 149
358 jgs 82 /**
359     \brief
360     */
361 woo409 757 FINLEY_DLL_API
362 jgs 82 virtual int getDim() const;
363 jgs 149
364     /**
365 jgs 82 \brief
366 gross 2533 Returns a status indicator of the domain. The status identifier should be unique over
367     the live time if the object but may be updated if changes to the domain happen, e.g.
368     modifications to its geometry.
369    
370     This has to be implemented by the actual Domain adapter.
371     */
372     FINLEY_DLL_API
373     virtual StatusType getStatus() const;
374    
375    
376     /**
377     \brief
378 ksteube 1754 Return the number of data points summed across all MPI processes
379     */
380     FINLEY_DLL_API
381     virtual int getNumDataPointsGlobal() const;
382    
383     /**
384     \brief
385 jgs 82 Return the number of data points per sample, and the number of samples as a pair.
386 jgs 121 \param functionSpaceCode Input -
387 jgs 82 */
388 woo409 757 FINLEY_DLL_API
389 jgs 82 virtual std::pair<int,int> getDataShape(int functionSpaceCode) const;
390    
391     /**
392     \brief
393     copies the location of data points into arg. The domain of arg has to match this.
394     has to be implemented by the actual Domain adapter.
395     */
396 woo409 757 FINLEY_DLL_API
397 jgs 82 virtual void setToX(escript::Data& arg) const;
398 jgs 149
399 jgs 82 /**
400     \brief
401 gross 1044 sets a map from a clear tag name to a tag key
402     \param name Input - tag name.
403     \param tag Input - tag key.
404     */
405     FINLEY_DLL_API
406     virtual void setTagMap(const std::string& name, int tag);
407    
408     /**
409     \brief
410     Return the tag key for tag name.
411     \param name Input - tag name
412     */
413     FINLEY_DLL_API
414     virtual int getTag(const std::string& name) const;
415    
416     /**
417     \brief
418     Returns true if name is a defined tage name.
419     \param name Input - tag name to be checked.
420     */
421     FINLEY_DLL_API
422     virtual bool isValidTagName(const std::string& name) const;
423    
424     /**
425     \brief
426     Returns all tag names in a single string sperated by commas
427     */
428     FINLEY_DLL_API
429     virtual std::string showTagNames() const;
430    
431     /**
432     \brief
433 jgs 82 assigns new location to the domain
434     */
435 woo409 757 FINLEY_DLL_API
436 jgs 82 virtual void setNewX(const escript::Data& arg);
437 jgs 149
438 jgs 82 /**
439     \brief
440     interpolates data given on source onto target where source and target have to be given on the same domain.
441     */
442 woo409 757 FINLEY_DLL_API
443 jgs 82 virtual void interpolateOnDomain(escript::Data& target,const escript::Data& source) const;
444 jfenwick 2521
445    
446 woo409 757 FINLEY_DLL_API
447 jgs 82 virtual bool probeInterpolationOnDomain(int functionSpaceType_source,int functionSpaceType_target) const;
448 jgs 149
449 jgs 82 /**
450 jfenwick 2635 \brief given a vector of FunctionSpace typecodes, pass back a code which then can all be interpolated to.
451     \return true is result is valid, false if not
452     */
453     FINLEY_DLL_API
454     bool
455     commonFunctionSpace(const std::vector<int>& fs, int& resultcode) const;
456    
457     /**
458 jgs 82 \brief
459     interpolates data given on source onto target where source and target are given on different domains.
460     has to be implemented by the actual Domain adapter.
461     */
462 woo409 757 FINLEY_DLL_API
463 jgs 82 virtual void interpolateACross(escript::Data& target, const escript::Data& source) const;
464 jfenwick 2521
465     /**
466     \brief determines whether interpolation from source to target is possible.
467     Must be implemented by the actual Domain adapter
468     */
469 woo409 757 FINLEY_DLL_API
470 jfenwick 2521 virtual bool probeInterpolationACross(int functionSpaceType_source,const escript::AbstractDomain& targetDomain, int functionSpaceType_target) const;
471 jgs 149
472 jgs 82 /**
473     \brief
474 jgs 149 copies the surface normals at data points into out. The actual function space to be considered
475 jgs 82 is defined by out. out has to be defined on this.
476     */
477 woo409 757 FINLEY_DLL_API
478 jgs 82 virtual void setToNormal(escript::Data& out) const;
479 jgs 149
480 jgs 82 /**
481     \brief
482     copies the size of samples into out. The actual function space to be considered
483     is defined by out. out has to be defined on this.
484     */
485 woo409 757 FINLEY_DLL_API
486 jgs 82 virtual void setToSize(escript::Data& out) const;
487    
488     /**
489     \brief
490     copies the gradient of arg into grad. The actual function space to be considered
491     for the gradient is defined by grad. arg and grad have to be defined on this.
492     */
493 woo409 757 FINLEY_DLL_API
494 jgs 82 virtual void setToGradient(escript::Data& grad,const escript::Data& arg) const;
495    
496     /**
497     \brief
498     copies the integrals of the function defined by arg into integrals.
499     arg has to be defined on this.
500     */
501 woo409 757 FINLEY_DLL_API
502 jgs 82 virtual void setToIntegrals(std::vector<double>& integrals,const escript::Data& arg) const;
503    
504 jgs 149 /**
505 jgs 102 \brief
506 gross 1859 return the identifier of the matrix type to be used for the global stiffness matrix when a particular solver, package, perconditioner,
507 jgs 102 and symmetric matrix is used.
508     \param solver
509 jfenwick 2519 \param preconditioner
510     \param package
511 jgs 102 \param symmetry
512     */
513 woo409 757 FINLEY_DLL_API
514 gross 1859 virtual int getSystemMatrixTypeId(const int solver, const int preconditioner, const int package, const bool symmetry) const;
515 jgs 102
516 jgs 82 /**
517     \brief
518 gross 1859 return the identifier of the transport problem type to be used when a particular solver, perconditioner, package
519     and symmetric matrix is used.
520     \param solver
521 jfenwick 2519 \param preconditioner
522     \param package
523 gross 1859 \param symmetry
524     */
525     FINLEY_DLL_API
526     virtual int getTransportTypeId(const int solver, const int preconditioner, const int package, const bool symmetry) const;
527    
528     /**
529     \brief
530 jgs 82 returns true if data on this domain and a function space of type functionSpaceCode has to
531     considered as cell centered data.
532     */
533 woo409 757 FINLEY_DLL_API
534 jgs 82 virtual bool isCellOriented(int functionSpaceCode) const;
535 jgs 149
536 jgs 82 /**
537     \brief
538 jgs 153 Saves a dictonary of Data objects to an OpenDX input file. The keywords are used as identifier
539    
540     This has to be implemented by the actual Domain adapter.
541 jgs 82 */
542 woo409 757 FINLEY_DLL_API
543 jgs 153 virtual void saveDX(const std::string& filename,const boost::python::dict& arg) const;
544 jgs 149
545 jgs 153
546 jgs 82 /**
547     \brief
548 jgs 153 Saves a dictonary of Data objects to an VTK XML input file. The keywords are used as identifier
549    
550     This has to be implemented by the actual Domain adapter.
551 jgs 110 */
552 woo409 757 FINLEY_DLL_API
553 gross 2421 virtual void saveVTK(const std::string& filename,const boost::python::dict& arg, const std::string& metadata, const std::string& metadata_schema) const;
554 jgs 149
555 jfenwick 2642 FINLEY_DLL_API
556     virtual bool ownSample(int fs_code, index_t id) const;
557    
558 jgs 110 /**
559     \brief
560 jgs 82 returns the function space representation of the type functionSpaceCode on this domain
561     as a vtkObject.
562     */
563     // vtkObject createVtkObject(int functionSpaceCode) const;
564 jgs 149
565 jgs 82 /**
566     \brief
567     adds a PDE onto the stiffness matrix mat and a rhs
568     */
569 woo409 757 FINLEY_DLL_API
570 jgs 82 virtual void addPDEToSystem(
571     SystemMatrixAdapter& mat, escript::Data& rhs,
572     const escript::Data& A, const escript::Data& B, const escript::Data& C,
573 jgs 102 const escript::Data& D, const escript::Data& X, const escript::Data& Y,
574     const escript::Data& d, const escript::Data& y,
575     const escript::Data& d_contact, const escript::Data& y_contact) const;
576 gross 1204 /**
577     \brief
578     adds a PDE onto the lumped stiffness matrix matrix
579     */
580     FINLEY_DLL_API
581     virtual void addPDEToLumpedSystem(
582     escript::Data& mat,
583     const escript::Data& D,
584     const escript::Data& d) const;
585 jgs 149
586 jgs 82 /**
587     \brief
588 jgs 102 adds a PDE onto the stiffness matrix mat and a rhs
589 jgs 82 */
590 woo409 757 FINLEY_DLL_API
591 jgs 102 virtual void addPDEToRHS(escript::Data& rhs,
592     const escript::Data& X, const escript::Data& Y,
593     const escript::Data& y, const escript::Data& y_contact) const;
594 gross 1367 /**
595     \brief
596     adds a PDE onto a transport problem
597     */
598 jgs 149
599 gross 1367 FINLEY_DLL_API
600     virtual void addPDEToTransportProblem(
601     TransportProblemAdapter& tp, escript::Data& source,
602     const escript::Data& M,
603     const escript::Data& A, const escript::Data& B, const escript::Data& C,const escript::Data& D,
604     const escript::Data& X,const escript::Data& Y,
605     const escript::Data& d, const escript::Data& y,
606     const escript::Data& d_contact,const escript::Data& y_contact) const;
607    
608    
609 jgs 82 /**
610     \brief
611 gross 1366 creates a SystemMatrixAdapter stiffness matrix and initializes it with zeros:
612 jgs 82 */
613 woo409 757 FINLEY_DLL_API
614 jgs 82 SystemMatrixAdapter newSystemMatrix(
615     const int row_blocksize,
616     const escript::FunctionSpace& row_functionspace,
617     const int column_blocksize,
618     const escript::FunctionSpace& column_functionspace,
619 jgs 102 const int type) const;
620 gross 1366 /**
621     \brief
622     creates a TransportProblemAdapter
623 jgs 82
624 gross 1366 */
625    
626     FINLEY_DLL_API
627     TransportProblemAdapter newTransportProblem(
628     const double theta,
629     const int blocksize,
630     const escript::FunctionSpace& functionspace,
631     const int type) const;
632    
633 jgs 102 /**
634     \brief returns locations in the FEM nodes
635     */
636 woo409 757 FINLEY_DLL_API
637 jgs 102 virtual escript::Data getX() const;
638 jgs 149
639 jgs 102 /**
640     \brief return boundary normals at the quadrature point on the face elements
641     */
642 woo409 757 FINLEY_DLL_API
643 jgs 102 virtual escript::Data getNormal() const;
644 jgs 149
645 jgs 102 /**
646     \brief returns the element size
647     */
648 woo409 757 FINLEY_DLL_API
649 jgs 102 virtual escript::Data getSize() const;
650    
651 jgs 149 /**
652     \brief comparison operators
653     */
654 woo409 757 FINLEY_DLL_API
655 jfenwick 2521 virtual bool operator==(const escript::AbstractDomain& other) const;
656 woo409 757 FINLEY_DLL_API
657 jfenwick 2521 virtual bool operator!=(const escript::AbstractDomain& other) const;
658 jgs 102
659 gross 767 /**
660     \brief assigns new tag newTag to all samples of functionspace with a positive
661     value of mask for any its sample point.
662    
663     */
664     FINLEY_DLL_API
665     virtual void setTags(const int functionSpaceType, const int newTag, const escript::Data& mask) const;
666    
667 gross 1716 /**
668     \brief
669     return the number of tags in use and a pointer to an array with the number of tags in use
670     */
671     FINLEY_DLL_API
672     virtual int getNumberOfTagsInUse(int functionSpaceCode) const;
673    
674     FINLEY_DLL_API
675 jfenwick 2487 virtual const int* borrowListOfTagsInUse(int functionSpaceCode) const;
676 gross 1716
677 jfenwick 1802
678     /**
679     \brief Checks if this domain allows tags for the specified functionSpaceCode.
680     */
681     FINLEY_DLL_API
682     virtual
683     bool canTag(int functionSpaceCode) const;
684    
685    
686 jgs 82 protected:
687    
688     private:
689 caltinay 2151 void extractArgsFromDict(const boost::python::dict& arg, int& numData,
690     char**& names, escriptDataC*& data,
691     escriptDataC**& dataPtr) const;
692 jgs 149
693 jgs 82 //
694     // pointer to the externally created finley mesh
695     boost::shared_ptr<Finley_Mesh> m_finleyMesh;
696    
697     static FunctionSpaceNamesMapType m_functionSpaceTypeNames;
698    
699     };
700    
701     } // end of namespace
702 jgs 149
703 jgs 82 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26