~fluidity-core/fluidity/DG_Neumann

« back to all changes in this revision

Viewing changes to libspud/diamond/diamond/mixedtree.py

  • Committer: Timothy Bond
  • Date: 2011-12-06 11:38:19 UTC
  • mfrom: (3871.1.4 fix-diamond-4.1.1)
  • Revision ID: timothy.bond@imperial.ac.uk-20111206113819-n6utj7qfkerze9ul
This merge supplies:

* An updated version of libspud
* An install target for diamond in the root fluidity makefile
* A target in the root fluidity makefile to install user schemata

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
#    This file is part of Diamond.
 
4
#
 
5
#    Diamond is free software: you can redistribute it and/or modify
 
6
#    it under the terms of the GNU General Public License as published by
 
7
#    the Free Software Foundation, either version 3 of the License, or
 
8
#    (at your option) any later version.
 
9
#
 
10
#    Diamond is distributed in the hope that it will be useful,
 
11
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
#    GNU General Public License for more details.
 
14
#
 
15
#    You should have received a copy of the GNU General Public License
 
16
#    along with Diamond.  If not, see <http://www.gnu.org/licenses/>.
 
17
 
 
18
import plist
 
19
 
 
20
class MixedTree:
 
21
  def __init__(self, parent, child):
 
22
    """
 
23
    The .doc and .attrs comes from parent, and the .data comes from child. This
 
24
    is used to hide integer_value etc. from the left hand side, but for its data
 
25
    entry to show up on the right.
 
26
    """
 
27
 
 
28
    self.parent = parent
 
29
    self.child = child
 
30
 
 
31
    self.name = parent.name
 
32
    self.schemaname = parent.schemaname
 
33
    self.attrs = self.parent.attrs
 
34
    self.children = parent.children
 
35
    self.datatype = child.datatype
 
36
    self.data = child.data
 
37
    self.doc = parent.doc
 
38
    self.active = parent.active
 
39
 
 
40
    return
 
41
 
 
42
  def set_attr(self, attr, val):
 
43
    self.parent.set_attr(attr, val)
 
44
 
 
45
    return
 
46
 
 
47
  def get_attr(self, attr):
 
48
    return self.parent.get_attr(attr)
 
49
 
 
50
  def set_data(self, data):
 
51
    self.child.set_data(data)
 
52
    self.datatype = self.child.datatype
 
53
    self.data = self.child.data
 
54
 
 
55
    return
 
56
 
 
57
  def valid_data(self, datatype, data):
 
58
    return self.child.valid_data(datatype, data)
 
59
 
 
60
  def validity_check(self, datatype, data):
 
61
    return self.child.validity_check(datatype, data)
 
62
 
 
63
  def matches(self, text, case_sensitive = False):
 
64
    old_parent_data = self.parent.data
 
65
    self.parent.data = None
 
66
    parent_matches = self.parent.matches(text, case_sensitive)
 
67
    self.parent.data = old_parent_data
 
68
 
 
69
    if parent_matches:
 
70
      return True
 
71
 
 
72
    if case_sensitive:
 
73
      text_re = re.compile(text)
 
74
    else:
 
75
      text_re = re.compile(text, re.IGNORECASE)
 
76
 
 
77
    if not self.child.data is None and not text_re.search(self.child.data) is None:
 
78
      return True
 
79
    else:
 
80
      return False
 
81
 
 
82
  def is_comment(self):
 
83
    return self.parent.is_comment()
 
84
 
 
85
  def get_comment(self):
 
86
    return self.parent.get_comment()
 
87
 
 
88
  def is_tensor(self, geometry_dim_tree):
 
89
    """
 
90
    Perform a series of tests on the current MixedTree, to determine if
 
91
    it is intended to be used to store tensor or vector data.
 
92
    """
 
93
 
 
94
    # Check that a geometry is defined
 
95
    if geometry_dim_tree is None:
 
96
      return False
 
97
 
 
98
    # Check that this element has calculable and positive dimensions
 
99
      try:
 
100
        dim1, dim2 = self.tensor_shape(geometry_dim_tree)
 
101
        assert dim1 > 0
 
102
        assert dim2 > 0
 
103
      except AssertionError:
 
104
        return False
 
105
 
 
106
    # The element must have dim1, rank and shape attributes
 
107
    if "dim1" not in self.child.attrs.keys() \
 
108
       or "rank" not in self.child.attrs.keys() \
 
109
       or "shape" not in self.child.attrs.keys():
 
110
      return False
 
111
 
 
112
    # The dim1 and rank attributes must be of fixed type
 
113
    if self.child.attrs["dim1"][0] != "fixed" or self.child.attrs["rank"][0] != "fixed":
 
114
      return False
 
115
 
 
116
    if "dim2" in self.child.attrs.keys():
 
117
      # If a dim2 attribute is specified, it must be of fixed type and the rank must be 2
 
118
      # Also, the shape attribute must be a list of integers with cardinality equal to the rank
 
119
      if self.child.attrs["dim2"][0] != "fixed" \
 
120
         or self.child.attrs["rank"][1] != "2" \
 
121
         or not isinstance(self.child.attrs["shape"][0], plist.List) \
 
122
         or self.child.attrs["shape"][0].datatype is not int \
 
123
         or str(self.child.attrs["shape"][0].cardinality) != self.child.attrs["rank"][1]:
 
124
        return False
 
125
 
 
126
    # Otherwise, the rank must be one and the shape an integer
 
127
    elif self.child.attrs["rank"][1] != "1" or self.child.attrs["shape"][0] is not int:
 
128
      return False
 
129
 
 
130
    # The data for the element must be a list of one or more
 
131
    if not isinstance(self.datatype, plist.List) or self.datatype.cardinality != "+":
 
132
      return False
 
133
 
 
134
    # If the shape has been set, check that it has a valid value
 
135
    if self.child.attrs["shape"][1] != None:
 
136
      if geometry_dim_tree.data is None:
 
137
        return False
 
138
 
 
139
      dim1, dim2 = self.tensor_shape(geometry_dim_tree)
 
140
      if "dim2" in self.child.attrs.keys():
 
141
        if self.child.attrs["shape"][1] != str(dim1) + " " + str(dim2):
 
142
          return False
 
143
      elif self.child.attrs["shape"][1] != str(dim1):
 
144
        return False
 
145
 
 
146
    return True
 
147
 
 
148
  def tensor_shape(self, dimension):
 
149
    """
 
150
    Read the tensor shape for tensor or vector data in the current MixedTree.
 
151
    """
 
152
 
 
153
    if not isinstance(dimension, int):
 
154
      dimension = int(dimension.data)
 
155
 
 
156
    dim1 = 1
 
157
    dim2 = 1
 
158
    if "dim1" in self.child.attrs.keys():
 
159
      dim1 = int(eval(self.child.attrs["dim1"][1], {"dim":dimension}))
 
160
      if "dim2" in self.child.attrs.keys():
 
161
        dim2 = int(eval(self.child.attrs["dim2"][1], {"dim":dimension}))
 
162
 
 
163
    return (dim1, dim2)
 
164
 
 
165
  def is_symmetric_tensor(self, geometry):
 
166
    """
 
167
    Read if the tensor data in the current MixedTree is symmetric.
 
168
    """
 
169
 
 
170
    dim1, dim2 = self.tensor_shape(geometry)
 
171
 
 
172
    return dim1 == dim2 and "symmetric" in self.child.attrs.keys() and self.child.attrs["symmetric"][1] == "true"
 
173
 
 
174
  def is_python_code(self):
 
175
    """
 
176
    Perform a series of tests on the current MixedTree, to determine if
 
177
    it is intended to be used to store python code data.
 
178
    """
 
179
 
 
180
    try:
 
181
       lang = self.get_attr("language")
 
182
       if lang == "python":
 
183
         return True
 
184
    except:
 
185
      pass
 
186
 
 
187
    if self.datatype is not str:
 
188
      return False
 
189
 
 
190
    if "type" in self.child.attrs.keys():
 
191
      return self.child.attrs["type"][1] == "python"
 
192
    
 
193
    return False
 
194
 
 
195
  def get_name_path(self, leaf = True):
 
196
    return self.parent.get_name_path(leaf)
 
197
 
 
198
  def is_sliceable(self):
 
199
    return True