diff --git a/HySoP/hysop/domain/subsets/control_box.py b/HySoP/hysop/domain/control_box.py similarity index 98% rename from HySoP/hysop/domain/subsets/control_box.py rename to HySoP/hysop/domain/control_box.py index 53e161aeb3bc60dca47729acac67dc6ad4148473..2c3bd2214030c074db8de62de079d1017820892b 100644 --- a/HySoP/hysop/domain/subsets/control_box.py +++ b/HySoP/hysop/domain/control_box.py @@ -1,5 +1,5 @@ """Define a volume of control inside a domain (volume + all faces)""" -from hysop.domain.subsets.boxes import SubBox +from hysop.domain.subsets import SubBox import numpy as np import hysop.tools.numpywrappers as npw @@ -11,7 +11,6 @@ class ControlBox(SubBox): and set of indices belonging to surfaces of this domain (slices members). Useful to define control volume to perform integration. """ - def __init__(self, **kwds): super(ControlBox, self).__init__(**kwds) diff --git a/HySoP/hysop/domain/subsets/porous.py b/HySoP/hysop/domain/porous.py similarity index 98% rename from HySoP/hysop/domain/subsets/porous.py rename to HySoP/hysop/domain/porous.py index d8fe97bab1070041f863712a80e6ec28bf9838d0..f57fe564374ede00bb0e3e43653a92c60131262f 100644 --- a/HySoP/hysop/domain/subsets/porous.py +++ b/HySoP/hysop/domain/porous.py @@ -1,10 +1,8 @@ """Pre-defined subsets as combination of basic geometries. """ -from hysop.domain.subsets.subset import Subset -from hysop.domain.subsets.boxes import SubBox -from hysop.domain.subsets.sphere import Sphere, HemiSphere -from hysop.domain.subsets.cylinder import Cylinder, HemiCylinder +from hysop.domain.subsets import Subset, Sphere, HemiSphere +from hysop.domain.subsets import Cylinder, HemiCylinder, SubBox import hysop.tools.numpywrappers as npw from hysop.mpi.topology import Cartesian import numpy as np diff --git a/HySoP/hysop/domain/subsets/submesh.py b/HySoP/hysop/domain/submesh.py similarity index 100% rename from HySoP/hysop/domain/subsets/submesh.py rename to HySoP/hysop/domain/submesh.py diff --git a/HySoP/hysop/domain/subsets/subset.py b/HySoP/hysop/domain/subsets.py similarity index 53% rename from HySoP/hysop/domain/subsets/subset.py rename to HySoP/hysop/domain/subsets.py index bacc5eeea0dceffd0120a4cf85b5c618e1f35639..572620b8f2ae60aad420419403bfc66ce230a7ff 100644 --- a/HySoP/hysop/domain/subsets/subset.py +++ b/HySoP/hysop/domain/subsets.py @@ -1,4 +1,4 @@ -""" subset of a given domain. +""" subsets of a given domain (sphere ...) """ from hysop.domain.domain import Domain import numpy as np @@ -6,6 +6,7 @@ from hysop.mpi.topology import Cartesian from hysop.fields.discrete import DiscreteField import hysop.tools.numpywrappers as npw from hysop.fields.continuous import Field +from hysop.domain.submesh import SubMesh class Subset(object): @@ -18,8 +19,6 @@ class Subset(object): data[subset.slices] = ... or data[subset.tab] = ... - or - subset.apply(data) = ... slices : a list of python slices defining the grid points inside the subset ind : a tuple of arrays of indices @@ -86,6 +85,8 @@ class Subset(object): # where on_proc[topo] is true. Useful to reduce collective comm # on the subset self.subcomm = {} + # A box "around" the subset. + self._box = None def chi(self, *args): """Indicator function of the subset @@ -113,7 +114,16 @@ class Subset(object): assert isinstance(topo, Cartesian) if topo not in self.ind: dim = self._parent.dimension - self.ind[topo] = [np.where(self.chi(*topo.mesh.coords))] + if self._box is None: + self.ind[topo] = [np.where(self.chi(*topo.mesh.coords))] + else: + self._box.discretize(topo) + mesh = self._box.mesh[topo] + shift = mesh.local_start + self.ind[topo] = [np.where(self.chi(*mesh.coords))] + self.ind[topo][0] = tuple([self.ind[topo][0][d] + shift[d] + for d in xrange(dim)]) + self.on_proc[topo] = (np.asarray([len(self.ind[topo][0][i]) for i in xrange(dim)]) != 0).all() @@ -128,13 +138,6 @@ class Subset(object): subgroup = gtopo.Incl(rks) self.subcomm[topo] = topo.comm.Create(subgroup) - def apply(self, field): - """ - return field on the current subset - not yet implemented - """ - raise Exception('not yet implemented') - @staticmethod def intersection(slist, topo): """Compute the intersection of subsets @@ -460,3 +463,343 @@ class Subset(object): result = npw.real_sum(field[component][self.ind[topo][0]]) result *= dvol return result + + +class Sphere(Subset): + """ + Spherical domain. + """ + + def __init__(self, origin, radius=1.0, **kwds): + """ + Parameters + ---------- + origin : list or array + position of the center + radius : double, optional + kwds : base class parameters + + """ + def dist(*args): + size = len(args) + return npw.asarray(np.sqrt(sum([(args[d] - self.origin[d]) ** 2 + for d in xrange(size)])) + - self.radius) + + super(Sphere, self).__init__(chi=dist, **kwds) + # Radius of the sphere + self.radius = radius + # Center position + self.origin = npw.asrealarray(origin).copy() + dim = self._parent.dimension + # a subbox used to reduced the size of coords + # during dist computation. + self._box = SubBox(parent=self._parent, + length=[2 * self.radius, ] * dim, + origin=self.origin - self.radius) + + def __str__(self): + s = self.__class__.__name__ + ' of radius ' + str(self.radius) + s += ' and center position ' + str(self.origin) + return s + + +class HemiSphere(Sphere): + """ + HemiSpherical domain. + Area defined by the intersection of a sphere and a box. + The box is defined with : + - cutdir, normal direction to a plan + - cutpos, position of this plan along the 'cutdir" axis + - all points of the domain where x < xs. + """ + def __init__(self, cutpos=None, cutdir=0, **kwds): + """ + Parameters + ---------- + cutpos : list or array of coordinates + position of the cutting plane + cutdir : real, optional + direction of the normal to the cutting plane. + Default = x-direction (0). + """ + super(HemiSphere, self).__init__(**kwds) + # direction of normal to the cutting plane + self.cutdir = cutdir + if cutpos is None: + cutpos = self.origin[self.cutdir] + + def left_box(x): + return x - cutpos + self.LeftBox = left_box + + def chi(self, *args): + return np.logical_and(self._is_inside(*args) <= 0, + self.LeftBox(args[self.cutdir]) <= 0) + + +class Cylinder(Subset): + """ + Cylinder-like domain. + """ + + def __init__(self, origin, radius=1.0, axis=1, **kwds): + """ + Parameters + ---------- + origin : list or array + coordinates of the center + radius : double, optional + default = 1. + axis : int, optional + direction of the main axis of the cylinder, default=1 (y) + + """ + + def dist(*args): + size = len(self._dirs) + return npw.asarray(np.sqrt(sum([(args[self._dirs[d]] - + self.origin[self._dirs[d]]) ** 2 + for d in xrange(size)])) + - self.radius) + + super(Cylinder, self).__init__(chi=dist, **kwds) + ## Radius of the cylinder + self.radius = radius + ## Main axis position + self.origin = npw.asrealarray(origin).copy() + ## direction of the main axis of the cylinder + self.axis = axis + dim = self._parent.dimension + dirs = np.arange(dim) + self._dirs = np.where(dirs != self.axis)[0] + length = [2 * self.radius] * dim + length[self.axis] = self._parent.length[self.axis] + origin = self.origin - self.radius + origin[self.axis] = self._parent.origin[self.axis] + # a subbox used to reduced the size of coords + # during dist computation. + self._box = SubBox(parent=self._parent, + length=length, origin=origin) + + def chi(self, *args): + return np.logical_and(self._is_inside(*args) <= 0, + args[self.axis] == + args[self.axis]) + + def __str__(self): + s = self.__class__.__name__ + ' of radius ' + str(self.radius) + s += ' and center position ' + str(self.origin) + return s + + +class HemiCylinder(Cylinder): + """ + Half cylinder domain. + """ + def __init__(self, cutpos=None, cutdir=0, **kwds): + """A cylinder cut by a plane (normal to one axis dir). + + Parameters + ---------- + cutpos : list or array of coordinates + position of the cutting plane + cutdir : real, optional + direction of the normal to the cutting plane. + Default = x-direction (0). + + """ + super(HemiCylinder, self).__init__(**kwds) + # direction of normal to the cutting plane + self.cutdir = cutdir + if cutpos is None: + cutpos = self.origin[self.cutdir] + + def left_box(x): + return x - cutpos + self.LeftBox = left_box + + def chi(self, *args): + return (np.logical_and( + np.logical_and(self._is_inside(*args) <= 0, + self.LeftBox(args[self.cutdir]) <= 0), + args[self.axis] == args[self.axis])) + + +class SubBox(Subset): + """ + A rectangle (in 2 or 3D space), defined by the coordinates of + its lowest point, its lenghts and its normal. + """ + def __init__(self, origin, length, normal=1, **kwds): + """ + Parameters + ---------- + origin : list or array of double + position of the lowest point of the box + length : list or array of double + lengthes of the sides of the box + normal : int = 1 or -1, optional + direction of the outward normal. Only makes + sense when the 'box' is a plane. + **kwds : extra args for parent class + + """ + super(SubBox, self).__init__(**kwds) + ## Dictionnary of hysop.domain.mesh.Submesh, keys=topo, values=mesh + self.mesh = {} + ## coordinates of the lowest point of this subset + self.origin = npw.asrealarray(origin).copy() + ## length of this subset + self.length = npw.asrealarray(length).copy() + ## coordinates of the 'highest' point of this subset + self.end = self.origin + self.length + ## directions of coordinate axes belonging to the subset + self.t_dir = np.where(self.length != 0)[0] + ## directions of coordinate axes normal to the subset + self.n_dir = np.where(self.length == 0)[0] + ## direction of the outward unit normal (+ or - 1) + ## Useful when the surface belong to a control box. + self.normal = normal + msg = 'Subset error, the origin is outside of the domain.' + assert ((self.origin - self._parent.origin) >= 0).all(), msg + msg = 'Subset error, the subset is too large for the domain.' + assert ((self._parent.end - self.end) >= 0).all(), msg + ## dict of coordinates of the lengthes of the subset (values) + ## for a given topo (keys). If the origin/length does not + ## fit exactly with the mesh, there may be a small shift of + ## these values. + self.real_length = {} + ## dict of coordinates of the origin of the subset (values) + ## for a given topo (keys). If the origin/length does not + ## fit exactly with the mesh, there may be a small shift of + ## these values. + self.real_orig = {} + + self.chi = None + + def discretize(self, topo): + """ + Compute a local submesh on the subset, for a given topology + + :param topo: `~hysop.mpi.topology.Cartesian` + """ + assert isinstance(topo, Cartesian) + # Find the indices of starting/ending points in the global_end + # grid of the mesh of topo. + gstart = topo.mesh.global_indices(self.origin) + gend = topo.mesh.global_indices(self.origin + self.length) + # create a submesh + self.mesh[topo] = SubMesh(topo.mesh, gstart, gend) + self.real_length[topo] = self.mesh[topo].global_length + self.real_orig[topo] = self.mesh[topo].global_origin + self.on_proc[topo] = self.mesh[topo].on_proc + self.ind[topo] = [self.mesh[topo].iCompute] + self._reduce_topology(topo) + return self.ind[topo] + + def integrate_field_on_proc(self, field, topo, component=0): + """Field integration + + Parameters + ---------- + field : `~hysop.field.continuous.Field` + a field to be integrated on the box + topo : `~hysop.mpi.topology.Cartesian` + set mesh/topology used for integration + component : int, optional + number of the field component to be integrated + + Returns + -------- + integral of a component of the input field over the current subset, + on the current process + (i.e. no mpi reduce over all processes) for the discretization + given by topo.. + """ + assert isinstance(field, Field) + assert isinstance(topo, Cartesian) + df = field.discretize(topo) + dvol = npw.prod(topo.mesh.space_step[self.t_dir]) + ic = self.mesh[topo].ind4integ + result = npw.real_sum(df[component][ic]) + result *= dvol + return result + + def integrate_func(self, func, topo, nbc, root=None): + """Function integration + + Parameters + ---------- + func: python function of space coordinates + topo: `~hysop.mpi.topology.Cartesian` + set mesh/topology used for integration + nbc : int + number of components of the return value from func + + Returns + ------- + integral of a component of the input field + over the current subset, for the discretization given by + topo + """ + res = npw.zeros(nbc) + gres = npw.zeros(nbc) + for i in xrange(res.size): + res[i] = self.integrate_func_on_proc(func, topo) + if root is None: + topo.comm.Allreduce(res, gres) + else: + topo.comm.Reduce(res, gres, root=root) + return gres + + def integrate_func_on_proc(self, func, topo): + """Function local integration + + Parameters + ---------- + func: python function of space coordinates + topo: `~hysop.mpi.topology.Cartesian` + set mesh/topology used for integration + + Returns + -------- + integral of the function on the subset on the current process + (i.e. no mpi reduce over all processes) + """ + assert hasattr(func, '__call__') + assert isinstance(topo, Cartesian) + vfunc = np.vectorize(func) + if self.mesh[topo].on_proc: + result = npw.real_sum(vfunc(*self.mesh[topo].coords4int)) + else: + result = 0. + dvol = npw.prod(topo.mesh.space_step) + result *= dvol + return result + + def integrate_dfield_on_proc(self, field, component=0): + """Discrete field local integration + + Parameters + ---------- + field : `~hysop.field.discrete.DiscreteField` + a field to be integrated on the box + component : int, optional + number of the field component to be integrated + integrate the field on the subset on the current process + (i.e. no mpi reduce over all processes) for the discretization + given by topo. + + Returns + -------- + integral of the field on the subset on the current process + (i.e. no mpi reduce over all processes) + """ + assert isinstance(field, DiscreteField) + topo = field.topology + dvol = npw.prod(topo.mesh.space_step[self.t_dir]) + ic = self.mesh[topo].ind4integ + result = npw.real_sum(field[component][ic]) + result *= dvol + return result diff --git a/HySoP/hysop/domain/subsets/__init__.py b/HySoP/hysop/domain/subsets/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/HySoP/hysop/domain/subsets/boxes.py b/HySoP/hysop/domain/subsets/boxes.py deleted file mode 100644 index 41b665250c99e73e97b82b39127921c8fa38c09e..0000000000000000000000000000000000000000 --- a/HySoP/hysop/domain/subsets/boxes.py +++ /dev/null @@ -1,187 +0,0 @@ -"""2D rectangle or 3D Rectangular Cuboid subsets """ -from hysop.domain.subsets.subset import Subset -from hysop.domain.subsets.submesh import SubMesh -import hysop.tools.numpywrappers as npw -from hysop import Field -from hysop.fields.discrete import DiscreteField -import numpy as np -from hysop.mpi.topology import Cartesian - - -class SubBox(Subset): - """ - A rectangle (in 2 or 3D space), defined by the coordinates of - its lowest point, its lenghts and its normal. - """ - def __init__(self, origin, length, normal=1, **kwds): - """ - Parameters - ---------- - origin : list or array of double - position of the lowest point of the box - length : list or array of double - lengthes of the sides of the box - normal : int = 1 or -1, optional - direction of the outward normal. Only makes - sense when the 'box' is a plane. - **kwds : extra args for parent class - - """ - super(SubBox, self).__init__(**kwds) - ## Dictionnary of hysop.domain.mesh.Submesh, keys=topo, values=mesh - self.mesh = {} - ## coordinates of the lowest point of this subset - self.origin = npw.asrealarray(origin).copy() - ## length of this subset - self.length = npw.asrealarray(length).copy() - ## coordinates of the 'highest' point of this subset - self.end = self.origin + self.length - ## directions of coordinate axes belonging to the subset - self.t_dir = np.where(self.length != 0)[0] - ## directions of coordinate axes normal to the subset - self.n_dir = np.where(self.length == 0)[0] - ## direction of the outward unit normal (+ or - 1) - ## Useful when the surface belong to a control box. - self.normal = normal - msg = 'Subset error, the origin is outside of the domain.' - assert ((self.origin - self._parent.origin) >= 0).all(), msg - msg = 'Subset error, the subset is too large for the domain.' - assert ((self._parent.end - self.end) >= 0).all(), msg - ## dict of coordinates of the lengthes of the subset (values) - ## for a given topo (keys). If the origin/length does not - ## fit exactly with the mesh, there may be a small shift of - ## these values. - self.real_length = {} - ## dict of coordinates of the origin of the subset (values) - ## for a given topo (keys). If the origin/length does not - ## fit exactly with the mesh, there may be a small shift of - ## these values. - self.real_orig = {} - - self.chi = None - - def discretize(self, topo): - """ - Compute a local submesh on the subset, for a given topology - - :param topo: `~hysop.mpi.topology.Cartesian` - """ - assert isinstance(topo, Cartesian) - # Find the indices of starting/ending points in the global_end - # grid of the mesh of topo. - gstart = topo.mesh.global_indices(self.origin) - gend = topo.mesh.global_indices(self.origin + self.length) - # create a submesh - self.mesh[topo] = SubMesh(topo.mesh, gstart, gend) - self.real_length[topo] = self.mesh[topo].global_length - self.real_orig[topo] = self.mesh[topo].global_origin - self.on_proc[topo] = self.mesh[topo].on_proc - self.ind[topo] = [self.mesh[topo].iCompute] - self._reduce_topology(topo) - return self.ind[topo] - - def integrate_field_on_proc(self, field, topo, component=0): - """Field integration - - Parameters - ---------- - field : `~hysop.field.continuous.Field` - a field to be integrated on the box - topo : `~hysop.mpi.topology.Cartesian` - set mesh/topology used for integration - component : int, optional - number of the field component to be integrated - - Returns - -------- - integral of a component of the input field over the current subset, - on the current process - (i.e. no mpi reduce over all processes) for the discretization - given by topo.. - """ - assert isinstance(field, Field) - assert isinstance(topo, Cartesian) - df = field.discretize(topo) - dvol = npw.prod(topo.mesh.space_step[self.t_dir]) - ic = self.mesh[topo].ind4integ - result = npw.real_sum(df[component][ic]) - result *= dvol - return result - - def integrate_func(self, func, topo, nbc, root=None): - """Function integration - - Parameters - ---------- - func: python function of space coordinates - topo: `~hysop.mpi.topology.Cartesian` - set mesh/topology used for integration - nbc : int - number of components of the return value from func - - Returns - ------- - integral of a component of the input field - over the current subset, for the discretization given by - topo - """ - res = npw.zeros(nbc) - gres = npw.zeros(nbc) - for i in xrange(res.size): - res[i] = self.integrate_func_on_proc(func, topo) - if root is None: - topo.comm.Allreduce(res, gres) - else: - topo.comm.Reduce(res, gres, root=root) - return gres - - def integrate_func_on_proc(self, func, topo): - """Function local integration - - Parameters - ---------- - func: python function of space coordinates - topo: `~hysop.mpi.topology.Cartesian` - set mesh/topology used for integration - - Returns - -------- - integral of the function on the subset on the current process - (i.e. no mpi reduce over all processes) - """ - assert hasattr(func, '__call__') - assert isinstance(topo, Cartesian) - vfunc = np.vectorize(func) - if self.mesh[topo].on_proc: - result = npw.real_sum(vfunc(*self.mesh[topo].coords4int)) - else: - result = 0. - dvol = npw.prod(topo.mesh.space_step) - result *= dvol - return result - - def integrate_dfield_on_proc(self, field, component=0): - """Discrete field local integration - - Parameters - ---------- - field : `~hysop.field.discrete.DiscreteField` - a field to be integrated on the box - component : int, optional - number of the field component to be integrated - integrate the field on the subset on the current process - (i.e. no mpi reduce over all processes) for the discretization - given by topo. - - Returns - -------- - integral of the field on the subset on the current process - (i.e. no mpi reduce over all processes) - """ - assert isinstance(field, DiscreteField) - topo = field.topology - dvol = npw.prod(topo.mesh.space_step[self.t_dir]) - ic = self.mesh[topo].ind4integ - result = npw.real_sum(field[component][ic]) - result *= dvol - return result diff --git a/HySoP/hysop/domain/subsets/cylinder.py b/HySoP/hysop/domain/subsets/cylinder.py deleted file mode 100644 index ff73c96cf9696696dd2e6e1eabf8d3225137db15..0000000000000000000000000000000000000000 --- a/HySoP/hysop/domain/subsets/cylinder.py +++ /dev/null @@ -1,119 +0,0 @@ -"""Spherical or hemispherical subset. """ -from hysop.domain.subsets.subset import Subset -import numpy as np -import hysop.tools.numpywrappers as npw -from hysop.mpi.topology import Cartesian -from hysop.domain.subsets.boxes import SubBox - - -class Cylinder(Subset): - """ - Cylinder-like domain. - """ - - def __init__(self, origin, radius=1.0, axis=1, **kwds): - """ - Parameters - ---------- - origin : list or array - coordinates of the center - radius : double, optional - default = 1. - axis : int, optional - direction of the main axis of the cylinder, default=1 (y) - - """ - - def dist(*args): - size = len(self._dirs) - return npw.asarray(np.sqrt(sum([(args[self._dirs[d]] - - self.origin[self._dirs[d]]) ** 2 - for d in xrange(size)])) - - self.radius) - - super(Cylinder, self).__init__(chi=dist, **kwds) - ## Radius of the cylinder - self.radius = radius - ## Main axis position - self.origin = npw.asrealarray(origin).copy() - ## direction of the main axis of the cylinder - self.axis = axis - dim = self._parent.dimension - dirs = np.arange(dim) - self._dirs = np.where(dirs != self.axis)[0] - length = [2 * self.radius] * dim - length[self.axis] = self._parent.length[self.axis] - origin = self.origin - self.radius - origin[self.axis] = self._parent.origin[self.axis] - # a subbox used to reduced the size of coords - # during dist computation. - self._box = SubBox(parent=self._parent, - length=length, origin=origin) - - def discretize(self, topo): - assert isinstance(topo, Cartesian) - if topo not in self.ind: - self._box.discretize(topo) - mesh = self._box.mesh[topo] - shift = mesh.local_start - dim = self._parent.dimension - tmp = np.where(self.chi(*mesh.coords)) - self.ind[topo] = [tuple([tmp[d] + shift[d] for d in xrange(dim)])] - self.on_proc[topo] = (np.asarray([len(self.ind[topo][0][i]) - for i in xrange(dim)]) - != 0).all() - self._reduce_topology(topo) - return self.ind[topo] - - def chi(self, *args): - return np.logical_and(self._is_inside(*args) <= 0, - args[self.axis] == - args[self.axis]) - - def __str__(self): - s = self.__class__.__name__ + ' of radius ' + str(self.radius) - s += ' and center position ' + str(self.origin) - return s - - -class HemiCylinder(Cylinder): - """ - Half cylinder domain. - """ - def __init__(self, cutpos=None, cutdir=0, **kwds): - """ - A cylinder cut by a plane (normal to one axis dir). - @param cutpos : position of the cutting plane - @param cutdir : direction of the normal to the cutting plane. - Default = x-direction (0). - """ - super(HemiCylinder, self).__init__(**kwds) - ## direction of normal to the cutting plane - self.cutdir = cutdir - if cutpos is None: - cutpos = self.origin[self.cutdir] - - def LeftBox(x): - return x - cutpos - self.LeftBox = LeftBox - - def chi(self, *args): - return (np.logical_and( - np.logical_and(self._is_inside(*args) <= 0, - self.LeftBox(args[self.cutdir]) <= 0), - args[self.axis] == args[self.axis])) - - def discretize(self, topo): - if topo not in self.ind: - self._box.discretize(topo) - mesh = self._box.mesh[topo] - shift = mesh.local_start - dim = self._parent.dimension - tmp = np.where(self.chi(*mesh.coords)) - self.ind[topo] = [tuple([tmp[d] + shift[d] for d in xrange(dim)])] - self.on_proc[topo] = (np.asarray([len(self.ind[topo][0][i]) - for i in xrange(dim)]) - != 0).all() - self._reduce_topology(topo) - - return self.ind[topo] diff --git a/HySoP/hysop/domain/subsets/sphere.py b/HySoP/hysop/domain/subsets/sphere.py deleted file mode 100644 index c187584d14773c44383c5210456b31346e4a85d1..0000000000000000000000000000000000000000 --- a/HySoP/hysop/domain/subsets/sphere.py +++ /dev/null @@ -1,115 +0,0 @@ -"""Spherical or hemispherical subsets in 2 or 3D domains. - -""" -from hysop.domain.subsets.subset import Subset -import numpy as np -import hysop.tools.numpywrappers as npw -from hysop.mpi.topology import Cartesian -from hysop.domain.subsets.boxes import SubBox - - -class Sphere(Subset): - """ - Spherical domain. - """ - - def __init__(self, origin, radius=1.0, **kwds): - """ - Parameters - ---------- - origin : list or array - position of the center - radius : double, optional - kwds : base class parameters - - """ - def dist(*args): - size = len(args) - return npw.asarray(np.sqrt(sum([(args[d] - self.origin[d]) ** 2 - for d in xrange(size)])) - - self.radius) - - super(Sphere, self).__init__(chi=dist, **kwds) - # Radius of the sphere - self.radius = radius - # Center position - self.origin = npw.asrealarray(origin).copy() - dim = self._parent.dimension - # a subbox used to reduced the size of coords - # during dist computation. - self._box = SubBox(parent=self._parent, - length=[2 * self.radius, ] * dim, - origin=self.origin - self.radius) - - def discretize(self, topo): - assert isinstance(topo, Cartesian) - if topo not in self.ind: - self._box.discretize(topo) - mesh = self._box.mesh[topo] - shift = mesh.local_start - dim = self._parent.dimension - tmp = np.where(self.chi(*mesh.coords)) - self.ind[topo] = [tuple([tmp[d] + shift[d] - for d in xrange(dim)])] - self.on_proc[topo] = (np.asarray([len(self.ind[topo][0][i]) - for i in xrange(dim)]) - != 0).all() - self._reduce_topology(topo) - - return self.ind[topo] - - def __str__(self): - s = self.__class__.__name__ + ' of radius ' + str(self.radius) - s += ' and center position ' + str(self.origin) - return s - - -class HemiSphere(Sphere): - """ - HemiSpherical domain. - Area defined by the intersection of a sphere and a box. - The box is defined with : - - cutdir, normal direction to a plan - - cutpos, position of this plan along the 'cutdir" axis - - all points of the domain where x < xs. - """ - def __init__(self, cutpos=None, cutdir=0, **kwds): - """ - Parameters - ---------- - cutpos : list or array of coordinates - position of the cutting plane - cutdir : real, optional - direction of the normal to the cutting plane. - Default = x-direction (0). - """ - super(HemiSphere, self).__init__(**kwds) - # direction of normal to the cutting plane - self.cutdir = cutdir - if cutpos is None: - cutpos = self.origin[self.cutdir] - - def left_box(x): - return x - cutpos - self.LeftBox = left_box - - def chi(self, *args): - return np.logical_and(self._is_inside(*args) <= 0, - self.LeftBox(args[self.cutdir]) <= 0) - - def discretize(self, topo): - assert isinstance(topo, Cartesian) - if topo not in self.ind: - self._box.discretize(topo) - mesh = self._box.mesh[topo] - dim = self._parent.dimension - shift = mesh.local_start - self.ind[topo] = [np.where(self.chi(*mesh.coords))] - self.ind[topo][0] = tuple([self.ind[topo][0][d] + shift[d] - for d in xrange(dim)]) - self.on_proc[topo] = (np.asarray([len(self.ind[topo][0][i]) - for i in xrange(dim)]) - != 0).all() - self._reduce_topology(topo) - - return self.ind[topo] diff --git a/HySoP/hysop/domain/tests/test_subset.py b/HySoP/hysop/domain/tests/test_subset.py index 43577a5f96fcd31c858cbff477c78597e9b43357..73cc589ceefaa54b5ddbb5ded91c0806d277af62 100644 --- a/HySoP/hysop/domain/tests/test_subset.py +++ b/HySoP/hysop/domain/tests/test_subset.py @@ -9,8 +9,6 @@ from hysop.mpi.topology import Cartesian import hysop.tools.numpywrappers as npw import numpy as np import math -from hysop.mpi import main_size -import mpi4py Nx = 128 @@ -53,10 +51,10 @@ def check_subset(discr, fileref, class_name): assert hasattr(subs.chi, '__call__') subs.discretize(topo) assert subs.ind.keys()[0] == topo - assert len(subs.ind[topo]) == dom.dimension + assert len(subs.ind[topo][0]) == dom.dimension scal = Field(domain=topo.domain, is_vector=False) sd = scal.discretize(topo) - sd[0][subs.ind[topo]] = 2. + sd[0][subs.ind[topo][0]] = 2. iCompute = topo.mesh.iCompute return np.allclose(sd[0][iCompute], vd[0][iCompute]) @@ -123,11 +121,11 @@ def init_obst_list(discr, fileref): return np.allclose(sd[0][iCompute], vd[0][iCompute]) -def test_union_3D(): +def test_union_3d(): assert init_obst_list(discr3D, 'multi_obst_3d') -def test_union_2D(): +def test_union_2d(): assert init_obst_list(discr2D, 'multi_obst_2d') @@ -148,11 +146,11 @@ def init_subtract(discr, fileref): return np.allclose(sd[0][iCompute], vd[0][iCompute]) -def test_subtract_3D(): +def test_subtract_3d(): assert init_subtract(discr3D, 'multi_obst_subs_3d') -def test_subtract_2D(): +def test_subtract_2d(): assert init_subtract(discr2D, 'multi_obst_subs_2d') @@ -185,11 +183,11 @@ def init_subtract_lists(discr, fileref): return np.allclose(sd[0][topo.mesh.iCompute], vd[0][topo.mesh.iCompute]) -def test_subtract_list_3D(): +def test_subtract_list_3d(): assert init_subtract_lists(discr3D, 'multi_obst_subslist_3d') -def test_subtract_list_2D(): +def test_subtract_list_2d(): assert init_subtract_lists(discr2D, 'multi_obst_subslist_2d') @@ -201,9 +199,9 @@ if __name__ == "__main__": test_hemicylinder_3d() test_sphere_2d() test_hemisphere_2d() - test_union_2D() - test_union_3D() - test_subtract_3D() - test_subtract_2D() - test_subtract_list_3D() - test_subtract_list_2D() + test_union_2d() + test_union_3d() + test_subtract_3d() + test_subtract_2d() + test_subtract_list_3d() + test_subtract_list_2d() diff --git a/HySoP/hysop/operator/tests/test_penalization.py b/HySoP/hysop/operator/tests/test_penalization.py index b0cfb869253d6df3f9d913ec28c6d5caffaacd78..50e5915585f1ea65902153f7f0409721b3c403c5 100644 --- a/HySoP/hysop/operator/tests/test_penalization.py +++ b/HySoP/hysop/operator/tests/test_penalization.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -from hysop.domain.subsets.sphere import HemiSphere, Sphere -from hysop.domain.subsets.cylinder import Cylinder -from hysop.domain.subsets.porous import Porous +from hysop.domain.subsets import HemiSphere, Sphere, Cylinder +from hysop.domain.porous import Porous from hysop.operator.penalization import Penalization from hysop.operator.penalize_vorticity import PenalizeVorticity from hysop.problem.simulation import Simulation diff --git a/HySoP/setup.py.in b/HySoP/setup.py.in index dc78957d1a26ac017168d7de0d389be088c71836..b2489f6c80d3d38cc255be212f218ec1d3b479e2 100644 --- a/HySoP/setup.py.in +++ b/HySoP/setup.py.in @@ -13,7 +13,6 @@ name = '@PYPACKAGE_NAME@' # List of modules (directories) to be included packages = ['hysop', 'hysop.domain', - 'hysop.domain.subsets', 'hysop.fields', 'hysop.operator', 'hysop.operator.discrete',