source: inundation/pyvolution/pmesh2domain.py @ 3475

Last change on this file since 3475 was 2812, checked in by ole, 19 years ago

Forgot to pass caching arguments to Domain

File size: 7.6 KB
Line 
1"""Class pmesh2domain - Converting .tsh files to doamains
2
3
4   Copyright 2004
5   Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou
6   Geoscience Australia
7"""
8
9def pmesh_instance_to_domain_instance(mesh,
10                                      DomainClass):
11    """
12    Convert a pmesh instance/object into a domain instance.
13
14    Use pmesh_to_domain_instance to convert a mesh file to a domain instance.
15    """
16    import sys
17    from domain import Domain
18
19    vertex_coordinates, vertices, tag_dict, vertex_quantity_dict \
20                        ,tagged_elements_dict, geo_reference = \
21                        pmesh_to_domain(mesh_instance=mesh)
22
23
24    assert issubclass(DomainClass, Domain),"DomainClass is not a subclass of Domain."
25
26
27    domain = DomainClass(coordinates = vertex_coordinates,
28                         vertices = vertices,
29                         boundary = tag_dict,
30                         tagged_elements = tagged_elements_dict,
31                         geo_reference = geo_reference )
32
33    # set the water stage to be the elevation
34    if vertex_quantity_dict.has_key('elevation') and not vertex_quantity_dict.has_key('stage'):
35        vertex_quantity_dict['stage'] = vertex_quantity_dict['elevation']
36
37    domain.set_quantity_vertices_dict(vertex_quantity_dict)
38    #print "vertex_quantity_dict",vertex_quantity_dict
39    return domain
40
41
42
43def pmesh_to_domain_instance(file_name, DomainClass, use_cache = False, verbose = False):
44    """
45    Converts a mesh file(.tsh or .msh), to a Domain instance.
46
47    file_name is the name of the mesh file to convert, including the extension
48
49    DomainClass is the Class that will be returned.
50    It must be a subclass of Domain, with the same interface as domain.
51
52    use_cache: True means that caching is attempted for the computed domain.   
53    """
54
55    if use_cache is True:
56        from caching import cache
57        result = cache(_pmesh_to_domain_instance, (file_name, DomainClass),
58                       dependencies = [file_name],                     
59                       verbose = verbose)
60
61    else:
62        result = apply(_pmesh_to_domain_instance, (file_name, DomainClass))       
63       
64    return result
65
66
67
68
69def _pmesh_to_domain_instance(file_name, DomainClass):
70    """
71    Converts a mesh file(.tsh or .msh), to a Domain instance.
72
73    Internal function. See public interface pmesh_to_domain_instance for details
74    """
75   
76    import sys
77    from domain import Domain
78
79    vertex_coordinates, vertices, tag_dict, vertex_quantity_dict \
80                        ,tagged_elements_dict, geo_reference = \
81                        pmesh_to_domain(file_name=file_name)
82
83
84    assert issubclass(DomainClass, Domain),"DomainClass is not a subclass of Domain."
85
86
87    domain = DomainClass(coordinates = vertex_coordinates,
88                         vertices = vertices,
89                         boundary = tag_dict,
90                         tagged_elements = tagged_elements_dict,
91                         geo_reference = geo_reference )
92
93
94
95    #FIXME (Ole): Is this really the right place to apply the a default
96    #value specific to the shallow water wave equation?
97    #The 'assert' above indicates that any subclass of Domain is acceptable.
98    #Suggestion - module shallow_water.py will eventually take care of this
99    #(when I get around to it) so it should be removed from here.
100
101    # This doesn't work on the domain instance.
102    # This is still needed so -ve elevations don't cuase 'lakes'
103    # The fixme we discussed was to only create a quantity when its values
104    #are set.
105    # I think that's the way to go still
106
107    # set the water stage to be the elevation
108    if vertex_quantity_dict.has_key('elevation') and not vertex_quantity_dict.has_key('stage'):
109        vertex_quantity_dict['stage'] = vertex_quantity_dict['elevation']
110
111    domain.set_quantity_vertices_dict(vertex_quantity_dict)
112    #print "vertex_quantity_dict",vertex_quantity_dict
113    return domain
114
115
116def pmesh_to_domain(file_name=None,
117                    mesh_instance=None,
118                    use_cache=False,
119                    verbose=False):
120    """
121    Convert a pmesh file or a pmesh mesh instance to a bunch of lists
122    that can be used to instanciate a domain object.
123
124    use_cache: True means that caching is attempted for the computed domain.   
125    """
126 
127    if use_cache is True:
128        from caching import cache
129        result = cache(_pmesh_to_domain, (file_name, mesh_instance),
130                       dependencies = [file_name],                     
131                       verbose = verbose)
132
133    else:
134        result = apply(_pmesh_to_domain, (file_name, mesh_instance))       
135       
136    return result
137
138
139def _pmesh_to_domain(file_name=None,
140                     mesh_instance=None,
141                     use_cache=False,
142                     verbose=False):
143    """
144    Convert a pmesh file or a pmesh mesh instance to a bunch of lists
145    that can be used to instanciate a domain object.
146    """
147
148    from Numeric import transpose
149    from load_mesh.loadASCII import import_mesh_file
150
151    if file_name is None:
152        mesh_dict = mesh_instance.Mesh2IODict()
153    else:
154        mesh_dict = import_mesh_file(file_name)
155    #print "mesh_dict",mesh_dict
156    vertex_coordinates = mesh_dict['vertices']
157    volumes = mesh_dict['triangles']
158    vertex_quantity_dict = {}
159    point_atts = transpose(mesh_dict['vertex_attributes'])
160    point_titles  = mesh_dict['vertex_attribute_titles']
161    geo_reference  = mesh_dict['geo_reference']
162    for quantity, value_vector in map (None, point_titles, point_atts):
163        vertex_quantity_dict[quantity] = value_vector
164    tag_dict = pmesh_dict_to_tag_dict(mesh_dict)
165    tagged_elements_dict = build_tagged_elements_dictionary(mesh_dict)
166    return vertex_coordinates, volumes, tag_dict, vertex_quantity_dict, tagged_elements_dict, geo_reference
167
168
169
170def build_tagged_elements_dictionary(mesh_dict):
171    """Build the dictionary of element tags.
172    tagged_elements is a dictionary of element arrays,
173    keyed by tag:
174    { (tag): [e1, e2, e3..] }
175    """
176    tri_atts = mesh_dict['triangle_tags']
177    #print "tri_atts", tri_atts
178    tagged_elements = {}
179    for tri_att_index in range(len(tri_atts)):
180        tagged_elements.setdefault(tri_atts[tri_att_index],[]).append(tri_att_index)
181    #print "DSG pm2do tagged_elements", tagged_elements
182    return tagged_elements
183
184def pmesh_dict_to_tag_dict(mesh_dict):
185    """ Convert the pmesh dictionary (mesh_dict) description of boundary tags
186    to a dictionary of tags, indexed with volume id and face number.
187    """
188    triangles = mesh_dict['triangles']
189    sides = calc_sides(triangles)
190    tag_dict = {}
191    for seg, tag in map(None, mesh_dict['segments'],
192                        mesh_dict['segment_tags']):
193        v1 = seg[0]
194        v2 = seg[1]
195        for key in [(v1,v2),(v2,v1)]:
196            if sides.has_key(key) and tag <> "":
197                #"" represents null.  Don't put these into the dictionary
198                #this creates a dict of lists of faces, indexed by tag
199                #tagged_edges.setdefault(tag,[]).append(sides[key])
200                tag_dict[sides[key]] = tag
201
202    return tag_dict
203
204
205def calc_sides(triangles):
206    #Build dictionary mapping from sides (2-tuple of points)
207    #to left hand side neighbouring triangle
208    sides = {}
209    for id, triangle in enumerate(triangles):
210        a = triangle[0]
211        b = triangle[1]
212        c = triangle[2]
213        sides[a,b] = (id, 2) #(id, face)
214        sides[b,c] = (id, 0) #(id, face)
215        sides[c,a] = (id, 1) #(id, face)
216    return sides
Note: See TracBrowser for help on using the repository browser.