def test_pickle_csg(): import netgen.csg as csg geo = csg.CSGeometry() geo.Add(csg.Sphere(csg.Pnt(0,0,0), 2).bc("sphere")) brick = csg.OrthoBrick(csg.Pnt(-3,-3,-3), csg.Pnt(3,3,3)) geo.Add(csg.Cylinder(csg.Pnt(0,0,0), csg.Pnt(1,0,0), 0.5) * brick) geo.Add(csg.Ellipsoid(csg.Pnt(0,0,0), csg.Vec(1,0,0), csg.Vec(0,1,0), csg.Vec(0,0,0.5))) geo.Add(csg.Cone(csg.Pnt(0,0,0), csg.Pnt(3,0,0), 1, 0.5) * brick) geo.Add(csg.EllipticCone(csg.Pnt(0,0,0), csg.Vec(2,0,0), csg.Vec(0,1,0), 3, 0.5) * brick) geo.Add(csg.Torus(csg.Pnt(0,0,0), csg.Vec(0,1,0), 0.3, 0.05)) pts2d = [[1,1], [1,-1], [-1,-1], [-1,1]] segs = [[0,1], [1,2], [2,3], [3,0]] curve = csg.SplineCurve2d() pnrs = [curve.AddPoint(*p) for p in pts2d] for s in segs: curve.AddSegment(pnrs[s[0]], pnrs[s[1]]) geo.Add(csg.Revolution(csg.Pnt(0,0,0), csg.Pnt(1,0,0), curve)) path = csg.SplineCurve3d() pnts = [(0,0,0), (2,0,0), (2,2,0)] segs = [(0,1,2)] for pnt in pnts: path.AddPoint (*pnt) for seg in segs: path.AddSegment (*seg) geo.Add(csg.Extrusion(path, curve, csg.Vec(0,0,1))) geo_dump = pickle.dumps(geo) geo2 = pickle.loads(geo_dump) vd1 = geo._visualizationData() vd2 = geo2._visualizationData() for val1, val2 in zip(vd1.values(), vd2.values()): assert numpy.array_equal(val1, val2)
def __init__(self, pointa, pointb, radius, *, eps=csg_eps): unit = 1. * numpy.array(pointb) - numpy.array(pointa) unit /= numpy.linalg.norm(unit) eps *= radius super().__init__( netgen_csg.Cylinder(netgen_csg.Pnt(*pointa), netgen_csg.Pnt(*pointb), radius), csg_boundaries=[ dolfin.CompiledSubDomain( 'on_boundary && near((x[0]-p0)*(x[0]-p0) + (x[1]-p1)*(x[1]-p1) + (x[2]-p2)*(x[2]-p2) - ((x[0]-p0)*u0 + (x[1]-p1)*u1 + (x[2]-p2)*u2)*((x[0]-p0)*u0 + (x[1]-p1)*u1 + (x[2]-p2)*u2), rr, eps)', u0=unit[0], u1=unit[1], u2=unit[2], p0=pointa[0], p1=pointa[1], p2=pointa[2], rr=radius * radius, eps=eps) ])
def save(cls, network, phases=[], filename='', maxsize='auto', fileformat='STL Format', logger_level=0): r""" Saves (transient/steady-state) data from the given objects into the specified file. Parameters ---------- network : OpenPNM Network Object. The network containing the desired data. phases : list of OpenPNM Phase Objects (place holder, default is none). filename : string (optional). The name of the file containing the data to export. maxsize : a float or a string "auto" (optional). The maximum size of the mesh elements allowed. "auto" corresponds to an automatic determination based on pores and throats sizes. Any float value will be used as a maximum size. Small values result in finner meshes, but slower mesh calculations. fileformat : string (optional). Default is "STL Format" which corresponds to STL format. Other formats such as Gmsh and Fluent are supported (see ngsolve.org). logger_level : integer between 0 and 7 (optional). Default is 0. The logger level set in netgen package. Notes ----- This method only saves the geometry of the network, not any of the pore-scale models or other attributes. To save an actual OpenPNM Project use the ``Workspace`` object. """ try: import netgen.csg as csg except ModuleNotFoundError: logger.error('Module "netgen.csg" not found.') try: from netgen.meshing import SetMessageImportance as log log(logger_level) except ModuleNotFoundError: logger.warning('Module "netgen.meshing" not found. ' + 'The "logger_level" ignored.') project, network, phases = cls._parse_args(network=network, phases=phases) network = network[0] if filename == '': filename = project.name path = cls._parse_filename(filename=filename, ext='stl') # Path is a pathlib object, so slice it up as needed fname_stl = path.name # correct connections where 'pore.diameter' = 'throat.diameter' dt = network['throat.diameter'].copy() dp = network['pore.diameter'][network['throat.conns']] dt[dp[:, 0] == dt] *= 0.99 dt[dp[:, 1] == dt] *= 0.99 scale = max(network['pore.diameter'].max(), dt.max(), network['throat.length'].max()) if maxsize == 'auto': maxsize = min(network['pore.diameter'].min(), dt.min(), network['throat.length'].min()) geo = csg.CSGeometry() # define pores geometry = csg.Sphere( csg.Pnt(network['pore.coords'][0, 0] / scale, network['pore.coords'][0, 1] / scale, network['pore.coords'][0, 2] / scale), network['pore.diameter'][0] / scale / 2) for p in range(1, network.Np): pore = csg.Sphere( csg.Pnt(network['pore.coords'][p, 0] / scale, network['pore.coords'][p, 1] / scale, network['pore.coords'][p, 2] / scale), network['pore.diameter'][p] / scale / 2) geometry += pore # define throats for t in range(network.Nt): A = network['throat.endpoints.tail'][t, :] / scale B = network['throat.endpoints.head'][t, :] / scale V = (B - A) / _np.linalg.norm(B - A) plane1 = csg.Plane(csg.Pnt(A[0], A[1], A[2]), csg.Vec(-V[0], -V[1], -V[2])) plane2 = csg.Plane(csg.Pnt(B[0], B[1], B[2]), csg.Vec(V[0], V[1], V[2])) cylinder = csg.Cylinder(csg.Pnt(A[0], A[1], A[2]), csg.Pnt(B[0], B[1], B[2]), dt[t] / scale / 2) throat = cylinder * plane1 * plane2 geometry += throat # add pore and throats to geometry, build mesh, rescale, and export geo.Add(geometry) mesh = geo.GenerateMesh(maxh=maxsize / scale) mesh.Scale(scale) mesh.Export(filename=fname_stl, format=fileformat)