On Wed, Nov 13, 2013 at 10:53 AM, Daniel Wheeler <[email protected]>wrote:
> On Tue, Nov 12, 2013 at 4:30 PM, James Snyder <[email protected]> > wrote: > > Hi - > > > > I've been working with some meshes that I would like to cache. To prevent > > having to run Gmsh each time using the same mesh, I've tried using the > > read/write methods associated provided by tools.dump (I also tried raw > > cPickle-ing and using shelf) but I seem to be losing the physical and > > geometrical definitions created by makeMapVariables. Is there something > > I've missed or should I file a ticket on matforge? It also looks like we > > toss the mshFile so I don't believe I can just call > > gmshMesh.py:makeMapVariables again later. > > > > You havn't missed anything. After pickling the Gmsh mesh, it is really > just a standard mesh without any of the Gmsh attributes. > > > > Also would you be interested in caching mesh output for a given geometry > > description? > > That would be good for sure. > > > One could just hash incoming geometry descriptions and if > > meshing is successful save a temporary file object named using the > digest. > > I suppose this could be done in gmshMesh.py:openMSHFile? > > It makes sense. In that vein, I've done the following for the moment (which requires a cache directory to have been created): from fipy import * import hashlib import os, shutil cellSize = 0.05 radius = 1. gmsh_geometry = '''cellSize = %(cellSize)g; radius = %(radius)g; Point(1) = {0, 0, 0, cellSize}; Point(2) = {-radius, 0, 0, cellSize}; Point(3) = {0, radius, 0, cellSize}; Point(4) = {radius, 0, 0, cellSize}; Point(5) = {0, -radius, 0, cellSize}; Circle(6) = {2, 1, 3}; Circle(7) = {3, 1, 4}; Circle(8) = {4, 1, 5}; Circle(9) = {5, 1, 2}; Line Loop(10) = {6, 7, 8, 9}; Plane Surface(11) = {10}; Physical Surface("Circle") = {11}; ''' % locals() gmsh_geometry_hash = hashlib.sha1(gmsh_geometry).hexdigest() msh_cache_path = os.path.join('cache', "%s.msh" % (gmsh_geometry_hash)) if not os.path.exists(msh_cache_path): f_msh = openMSHFile(gmsh_geometry,dimensions=2) f_msh.close() shutil.copyfile(f_msh.filename, msh_cache_path) mesh = Gmsh2D(msh_cache_path) It's not perfect, I'm not sure what it does in parallel, but it does allow me to skip waiting for gmsh to do it's work when I want to re-use the same mesh and didn't require hacking the original sources. I'm not sure what the desired configuration would be for caching if something like this were made into a patch. I suppose it should still use the same system temporary file locations? > Below is a brutal hack to add physicalCells to make them pickle only > "physicalCells". There is undoubtedly a better way, but it is all I > could think of in a short time. It's a quick and dirty fix. It might > get you started on a better solution. > Thanks! I'll take a look at this too. This would save the need to reparse the mesh (not sure what percentage of time I'm spending in there currently). > > > import fipy as fp > import numpy as np > from fipy.meshes.representations.meshRepresentation import > _MeshRepresentation > > cellSize = 0.05 > radius = 1. > > class MyRepr(_MeshRepresentation): > def getstate(self): > state = super(MyRepr, self).getstate() > state['physicalCells'] = {k: np.array(v) for k, v in > self.mesh.physicalCells.iteritems()} > return state > > @staticmethod > def setstate(mesh, state): > physicalCells = state['physicalCells'] > del state['physicalCells'] > _MeshRepresentation.setstate(mesh, state) > mesh.physicalCells = physicalCells > > > old = fp.Gmsh2D(''' > cellSize = %(cellSize)g; > radius = %(radius)g; > Point(1) = {0, 0, 0, cellSize}; > Point(2) = {-radius, 0, 0, cellSize}; > Point(3) = {0, radius, 0, cellSize}; > Point(4) = {radius, 0, 0, cellSize}; > Point(5) = {0, -radius, 0, cellSize}; > Circle(6) = {2, 1, 3}; > Circle(7) = {3, 1, 4}; > Circle(8) = {4, 1, 5}; > Circle(9) = {5, 1, 2}; > Line Loop(10) = {6, 7, 8, 9}; > Plane Surface(11) = {10}; > Physical Surface("Circle") = {11}; > ''' % locals()) > > old.representation = MyRepr(mesh=old) > > f, tempfile = fp.dump.write(old) > new = fp.dump.read(tempfile, f) > > print old.physicalCells > print new.physicalCellsimport fipy as fp > import numpy as np > from fipy.meshes.representations.meshRepresentation import > _MeshRepresentation > > cellSize = 0.05 > radius = 1. > > class MyRepr(_MeshRepresentation): > def getstate(self): > state = super(MyRepr, self).getstate() > state['physicalCells'] = {k: np.array(v) for k, v in > self.mesh.physicalCells.iteritems()} > return state > > @staticmethod > def setstate(mesh, state): > physicalCells = state['physicalCells'] > del state['physicalCells'] > _MeshRepresentation.setstate(mesh, state) > mesh.physicalCells = physicalCells > > > old = fp.Gmsh2D(''' > cellSize = %(cellSize)g; > radius = %(radius)g; > Point(1) = {0, 0, 0, cellSize}; > Point(2) = {-radius, 0, 0, cellSize}; > Point(3) = {0, radius, 0, cellSize}; > Point(4) = {radius, 0, 0, cellSize}; > Point(5) = {0, -radius, 0, cellSize}; > Circle(6) = {2, 1, 3}; > Circle(7) = {3, 1, 4}; > Circle(8) = {4, 1, 5}; > Circle(9) = {5, 1, 2}; > Line Loop(10) = {6, 7, 8, 9}; > Plane Surface(11) = {10}; > Physical Surface("Circle") = {11}; > ''' % locals()) > > old.representation = MyRepr(mesh=old) > > f, tempfile = fp.dump.write(old) > new = fp.dump.read(tempfile, f) > > print old.physicalCells > print new.physicalCells > > > > -- > Daniel Wheeler > _______________________________________________ > fipy mailing list > [email protected] > http://www.ctcms.nist.gov/fipy > [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ] > -- James Snyder Biomedical Engineering Northwestern University ph: (847) 448-0386
_______________________________________________ fipy mailing list [email protected] http://www.ctcms.nist.gov/fipy [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
