source: inundation/pyvolution/pmesh2domain.py @ 3086

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

Forgot to pass caching arguments to Domain

File size: 7.6 KB
RevLine 
[374]1"""Class pmesh2domain - Converting .tsh files to doamains
[371]2
3
4   Copyright 2004
5   Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou
6   Geoscience Australia
7"""
8
[2056]9def pmesh_instance_to_domain_instance(mesh,
[2324]10                                      DomainClass):
[2056]11    """
[2605]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.
[2056]15    """
16    import sys
17    from domain import Domain
[371]18
[2056]19    vertex_coordinates, vertices, tag_dict, vertex_quantity_dict \
20                        ,tagged_elements_dict, geo_reference = \
[2607]21                        pmesh_to_domain(mesh_instance=mesh)
[2056]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
[2407]41
42
43def pmesh_to_domain_instance(file_name, DomainClass, use_cache = False, verbose = False):
[371]44    """
[2324]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.
[2407]51
52    use_cache: True means that caching is attempted for the computed domain.   
[371]53    """
[2407]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    """
[2319]75   
[371]76    import sys
[389]77    from domain import Domain
[371]78
[1556]79    vertex_coordinates, vertices, tag_dict, vertex_quantity_dict \
[1178]80                        ,tagged_elements_dict, geo_reference = \
[2607]81                        pmesh_to_domain(file_name=file_name)
[1556]82
83
[1178]84    assert issubclass(DomainClass, Domain),"DomainClass is not a subclass of Domain."
[636]85
86
[1556]87    domain = DomainClass(coordinates = vertex_coordinates,
88                         vertices = vertices,
89                         boundary = tag_dict,
[1178]90                         tagged_elements = tagged_elements_dict,
91                         geo_reference = geo_reference )
[371]92
[636]93
[1556]94
[636]95    #FIXME (Ole): Is this really the right place to apply the a default
96    #value specific to the shallow water wave equation?
[1556]97    #The 'assert' above indicates that any subclass of Domain is acceptable.
[636]98    #Suggestion - module shallow_water.py will eventually take care of this
[1556]99    #(when I get around to it) so it should be removed from here.
100
[905]101    # This doesn't work on the domain instance.
102    # This is still needed so -ve elevations don't cuase 'lakes'
[1178]103    # The fixme we discussed was to only create a quantity when its values
104    #are set.
[905]105    # I think that's the way to go still
[1556]106
[773]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']
[1556]110
[389]111    domain.set_quantity_vertices_dict(vertex_quantity_dict)
112    #print "vertex_quantity_dict",vertex_quantity_dict
113    return domain
[371]114
115
[2607]116def pmesh_to_domain(file_name=None,
[2808]117                    mesh_instance=None,
118                    use_cache=False,
119                    verbose=False):
[371]120    """
[2607]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.
[2808]123
124    use_cache: True means that caching is attempted for the computed domain.   
[371]125    """
[2808]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)
[1556]132
[2808]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,
[2812]140                     mesh_instance=None,
141                     use_cache=False,
142                     verbose=False):
[2808]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
[389]148    from Numeric import transpose
[1423]149    from load_mesh.loadASCII import import_mesh_file
[1556]150
[2324]151    if file_name is None:
[2056]152        mesh_dict = mesh_instance.Mesh2IODict()
153    else:
[2324]154        mesh_dict = import_mesh_file(file_name)
[389]155    #print "mesh_dict",mesh_dict
[968]156    vertex_coordinates = mesh_dict['vertices']
157    volumes = mesh_dict['triangles']
[389]158    vertex_quantity_dict = {}
[968]159    point_atts = transpose(mesh_dict['vertex_attributes'])
160    point_titles  = mesh_dict['vertex_attribute_titles']
[1178]161    geo_reference  = mesh_dict['geo_reference']
[389]162    for quantity, value_vector in map (None, point_titles, point_atts):
163        vertex_quantity_dict[quantity] = value_vector
[969]164    tag_dict = pmesh_dict_to_tag_dict(mesh_dict)
[415]165    tagged_elements_dict = build_tagged_elements_dictionary(mesh_dict)
[1556]166    return vertex_coordinates, volumes, tag_dict, vertex_quantity_dict, tagged_elements_dict, geo_reference
[371]167
168
169
[415]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    """
[969]176    tri_atts = mesh_dict['triangle_tags']
[415]177    #print "tri_atts", tri_atts
178    tagged_elements = {}
179    for tri_att_index in range(len(tri_atts)):
[1183]180        tagged_elements.setdefault(tri_atts[tri_att_index],[]).append(tri_att_index)
[415]181    #print "DSG pm2do tagged_elements", tagged_elements
182    return tagged_elements
[371]183
[969]184def pmesh_dict_to_tag_dict(mesh_dict):
[389]185    """ Convert the pmesh dictionary (mesh_dict) description of boundary tags
[969]186    to a dictionary of tags, indexed with volume id and face number.
[371]187    """
[968]188    triangles = mesh_dict['triangles']
[371]189    sides = calc_sides(triangles)
[969]190    tag_dict = {}
[2407]191    for seg, tag in map(None, mesh_dict['segments'],
192                        mesh_dict['segment_tags']):
[371]193        v1 = seg[0]
194        v2 = seg[1]
195        for key in [(v1,v2),(v2,v1)]:
[969]196            if sides.has_key(key) and tag <> "":
[686]197                #"" represents null.  Don't put these into the dictionary
[969]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
[686]201
[969]202    return tag_dict
[371]203
[1556]204
[371]205def calc_sides(triangles):
206    #Build dictionary mapping from sides (2-tuple of points)
[1556]207    #to left hand side neighbouring triangle
[371]208    sides = {}
209    for id, triangle in enumerate(triangles):
210        a = triangle[0]
211        b = triangle[1]
[1556]212        c = triangle[2]
[371]213        sides[a,b] = (id, 2) #(id, face)
214        sides[b,c] = (id, 0) #(id, face)
215        sides[c,a] = (id, 1) #(id, face)
[1556]216    return sides
Note: See TracBrowser for help on using the repository browser.