From d52d27d4bbaee38d4610b43a621edadd789fd0b7 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr> Date: Mon, 23 Jul 2018 22:09:54 +0200 Subject: [PATCH] added assertions for symbolic names --- examples/scalar_advection/scalar_advection.py | 1 - examples/scalar_diffusion/scalar_diffusion.py | 3 +- examples/shear_layer/shear_layer.py | 7 ++--- .../backend/device/opencl/opencl_symbolic.py | 31 +++++++++++-------- hysop/core/graph/computational_graph.py | 18 ----------- hysop/core/graph/computational_node.py | 31 +++++++++++++------ hysop/defaults.py | 2 +- hysop/fields/discrete_field.py | 4 +++ hysop/operator/adapt_timestep.py | 5 ++- hysop/operator/base/min_max.py | 2 +- .../tests/test_directional_advection.py | 11 ++++--- hysop/parameters/default_parameters.py | 9 ++++++ hysop/parameters/parameter.py | 4 +++ hysop/parameters/tensor_parameter.py | 23 +++++++++----- hysop/problem.py | 19 +++++++----- hysop/symbolic/__init__.py | 16 +++++++--- hysop/symbolic/base.py | 12 +++++-- hysop/symbolic/parameter.py | 14 ++++----- hysop/tools/sympy_utils.py | 13 ++++++-- hysop/tools/types.py | 2 ++ 20 files changed, 141 insertions(+), 86 deletions(-) diff --git a/examples/scalar_advection/scalar_advection.py b/examples/scalar_advection/scalar_advection.py index 534759ec2..25d99934b 100644 --- a/examples/scalar_advection/scalar_advection.py +++ b/examples/scalar_advection/scalar_advection.py @@ -12,7 +12,6 @@ def compute(args): ## Function to compute initial velocity values def init_velocity(data, coords, component): - print len(data), len(coords), component assert len(data)==1 i, = component data[0][...] = args.velocity[::-1][i] diff --git a/examples/scalar_diffusion/scalar_diffusion.py b/examples/scalar_diffusion/scalar_diffusion.py index 1bd86ac93..62ea8c52d 100755 --- a/examples/scalar_diffusion/scalar_diffusion.py +++ b/examples/scalar_diffusion/scalar_diffusion.py @@ -89,8 +89,7 @@ def compute(args): problem.display(args.visu_rank) # Initialize discrete scalar field - dfields = problem.input_discrete_fields - dfields[scalar].initialize(formula=init_scalar) + problem.initialize_field(scalar, formula=init_scalar) # Create a simulation and solve the problem # (do not forget to specify the dt parameter here) diff --git a/examples/shear_layer/shear_layer.py b/examples/shear_layer/shear_layer.py index 92f307bd8..52d924c31 100644 --- a/examples/shear_layer/shear_layer.py +++ b/examples/shear_layer/shear_layer.py @@ -10,7 +10,7 @@ def compute(args): ScalarParameter from hysop.tools.debug_utils import ImshowDebugger from hysop.defaults import VelocityField, VorticityField, \ - TimeParameters + TimeParameters, ViscosityParameter from hysop.constants import Implementation, AdvectionCriteria from hysop.operators import DirectionalAdvection, DirectionalDiffusion, \ @@ -78,7 +78,7 @@ def compute(args): t, dt = TimeParameters(dtype=args.dtype) velo = VelocityField(domain=box, dtype=args.dtype) vorti = VorticityField(domain=box, dtype=args.dtype) - nu = ScalarParameter('nu', initial_value=args.nu, const=True, dtype=args.dtype) + nu = ViscosityParameter(initial_value=args.nu, const=True, dtype=args.dtype) ### Build the directional operators #> Directional advection @@ -157,8 +157,7 @@ def compute(args): simu.write_parameters(t, dt, filename='parameters.txt', precision=4) # Initialize only the vorticity - dfields = problem.input_discrete_fields - dfields[vorti].initialize(formula=init_vorticity) + problem.initialize_field(vorti, formula=init_vorticity) # Setup vorticity plotter if required if args.plot_vorticity: diff --git a/hysop/backend/device/opencl/opencl_symbolic.py b/hysop/backend/device/opencl/opencl_symbolic.py index 3d33256ed..18adca261 100644 --- a/hysop/backend/device/opencl/opencl_symbolic.py +++ b/hysop/backend/device/opencl/opencl_symbolic.py @@ -83,18 +83,21 @@ class OpenClSymbolic(OpenClOperator): if ('count' in kwds): count = kwds.pop('count') assert len(names)==1 - snames = tuple(names[0]+subscript(i) for i in xrange(count)) + snames = tuple(names[0]+subscript(i) for i in xrange(count)) var_names = tuple('{}{}'.format(names[0], i) for i in xrange(count)) latex_names = tuple('{}_{{{}}}'.format(names[0], i) for i in xrange(count)) else: snames = names varnames = names latexnames = names - for (name, var_name, latex_name) in zip(snames, var_names, latex_names): + for (name, pname, var_name, latex_name) in zip(var_names, snames, var_names, latex_names): assert ',' not in name - check_instance(name, (str,unicode)) - buf = OpenClSymbolicBuffer(name=name, var_name=var_name, latex_name=latex_name, - memory_object=None, **kwds) + check_instance(name, str) + buf = OpenClSymbolicBuffer(name=name, + pretty_name=pname, + var_name=var_name, + latex_name=latex_name, + memory_object=None, **kwds) buffers += (buf,) return buffers @@ -112,11 +115,12 @@ class OpenClSymbolic(OpenClOperator): snames = names var_names = names latex_names = names - for (name, var_name, latex_name) in zip(snames, var_names, latex_names): + for (name, pname, var_name, latex_name) in zip(var_names, snames, var_names, latex_names): assert ',' not in name - check_instance(name, (str,unicode)) - arr = OpenClSymbolicArray(name=name, var_name=var_name, latex_name=latex_name, - memory_object=None, **kwds) + check_instance(name, str) + arr = OpenClSymbolicArray(name=name, pretty_name=pname, + var_name=var_name, latex_name=latex_name, + memory_object=None, **kwds) arrays += (arr,) return arrays @@ -134,11 +138,12 @@ class OpenClSymbolic(OpenClOperator): snames = names var_names = names latex_names = names - for (name, var_name, latex_name) in zip(snames, var_names, latex_names): + for (name, pname, var_name, latex_name) in zip(var_names, snames, var_names, latex_names): assert ',' not in name - check_instance(name, (str,unicode)) - tmp = TmpScalar(name=name, var_name=var_name, latex_name=latex_name, - **kwds) + check_instance(name, str) + tmp = TmpScalar(name=name, pretty_name=pname, + var_name=var_name, latex_name=latex_name, + **kwds) scalars += (tmp,) return scalars diff --git a/hysop/core/graph/computational_graph.py b/hysop/core/graph/computational_graph.py index 6d2e7b093..7c7919548 100644 --- a/hysop/core/graph/computational_graph.py +++ b/hysop/core/graph/computational_graph.py @@ -62,9 +62,6 @@ class ComputationalGraph(ComputationalGraphNode): self.graph_is_rendering = False self.candidate_input_tensors = set(first_not_None(candidate_input_tensors, ())) self.candidate_output_tensors = set(first_not_None(candidate_output_tensors, ())) - print self.name - print self.candidate_input_tensors - print self.candidate_output_tensors @graph_built def _get_profiling_info(self): @@ -386,10 +383,6 @@ class ComputationalGraph(ComputationalGraphNode): else: msg = 'Given node is not an instance of ComputationalGraphNode (got a {}).' raise ValueError(msg.format(node.__class__)) - print 'PUSH NODE {}'.format(node.name) - print self.name - print self.candidate_input_tensors - print self.candidate_output_tensors return self def available_methods(self): @@ -514,12 +507,6 @@ class ComputationalGraph(ComputationalGraphNode): output_fields = builder.output_fields candidate_input_tensors = self.candidate_input_tensors candidate_output_tensors = self.candidate_output_tensors - print - print 'BUILD GRAPH {}'.format(self.name) - print 'CANDIDATE_INPUT_TENSORS: {}'.format(tuple(f.name for f in candidate_input_tensors)) - print 'CANDIDATE_OUTPUT_TENSORS: {}'.format(tuple(f.name for f in candidate_output_tensors)) - print 'INPUT_FIELDS: {}'.format(tuple(f.name for f in input_fields)) - print 'OUTPUT_FIELDS: {}'.format(tuple(f.name for f in output_fields)) input_tensor_fields = () output_tensor_fields = () @@ -530,9 +517,6 @@ class ComputationalGraph(ComputationalGraphNode): if all((f in output_fields) for f in otfield): output_tensor_fields += (otfield,) - print 'INPUT_TENSORS: {}'.format( tuple(f.name for f in input_tensor_fields)) - print 'OUTPUT_TENSORS: {}'.format(tuple(f.name for f in output_tensor_fields)) - # keep variables self._init_base(input_fields=input_fields, output_fields=output_fields, @@ -624,7 +608,6 @@ class ComputationalGraph(ComputationalGraphNode): def discretize(self): if self.discretized: return - print 'DISCRETIZE {}'.format(self.name) reduced_graph = self.reduced_graph operators = reduced_graph.vertex_properties['operators'] for vid in self.sorted_nodes: @@ -688,7 +671,6 @@ class ComputationalGraph(ComputationalGraphNode): self.discrete_fields = discrete_fields self.discrete_tensor_fields = discrete_tensor_fields - print 'INPUT DISCRETE TENSOR FIELD:',tuple(f.name for f in self.input_discrete_tensor_fields) self.discretized = True diff --git a/hysop/core/graph/computational_node.py b/hysop/core/graph/computational_node.py index bb3d60164..c60ba7a04 100644 --- a/hysop/core/graph/computational_node.py +++ b/hysop/core/graph/computational_node.py @@ -188,7 +188,7 @@ class ComputationalGraphNode(OperatorBase): for sfield in tfield.fields } else: output_tensor_fields = () - + # Check input values input_fields = first_not_None(input_fields, {}) output_fields = first_not_None(output_fields, {}) @@ -306,6 +306,17 @@ class ComputationalGraphNode(OperatorBase): """ Initialize base class and check everything. """ + # Merge scalar and tensor fields + all_input_fields = tuple(input_tensor_fields) + for ofield in input_fields.keys(): + if not any (ofield in tf for tf in input_tensor_fields): + all_input_fields += (ofield,) + + all_output_fields = tuple(output_tensor_fields) + for ofield in output_fields.keys(): + if not any (ofield in tf for tf in output_tensor_fields): + all_output_fields += (ofield,) + assert not self._base_initialized check_instance(input_fields, dict, keys=ScalarField) check_instance(output_fields, dict, keys=ScalarField) @@ -313,6 +324,8 @@ class ComputationalGraphNode(OperatorBase): check_instance(output_params, dict, keys=str, values=Parameter) check_instance(input_tensor_fields, tuple, values=TensorField) check_instance(output_tensor_fields, tuple, values=TensorField) + check_instance(all_input_fields, tuple, values=Field) + check_instance(all_output_fields, tuple, values=Field) self.input_fields = input_fields self.output_fields = output_fields @@ -321,10 +334,6 @@ class ComputationalGraphNode(OperatorBase): self.input_tensor_fields = input_tensor_fields self.output_tensor_fields = output_tensor_fields - print - print 'INIT BASE {}'.format(self.name) - print 'INPUT TENSOR FIELDS:', tuple(f.name for f in self.input_tensor_fields) - ifields = set(self.input_fields.keys()) ofields = set(self.output_fields.keys()) fields = tuple(ifields.union(ofields)) @@ -354,6 +363,8 @@ class ComputationalGraphNode(OperatorBase): parameters=parameters, **self.__kwds) self._base_initialized = True + self.all_input_fields = all_input_fields + self.all_output_fields = all_output_fields @debug def _check_method(self, user_method): @@ -943,13 +954,14 @@ class ComputationalGraphNode(OperatorBase): check_instance(fields, (set,list,tuple), values=Field) if self._base_initialized: for field in fields: - if field not in self.input_fields.keys(): + if ((field not in self.input_fields) and \ + (field not in self.input_tensor_fields)): msg='Field {} is not an input field of operator {}.' msg=msg.format(field.name, self.name) raise RuntimeError(msg) else: assert self._base_initialized, self.name - fields = self.input_fields.keys() + fields = self.all_input_fields fields = list(sorted(fields, key=lambda f:f.name)) if (io_params is None): @@ -994,12 +1006,13 @@ class ComputationalGraphNode(OperatorBase): check_instance(fields, (set,list,tuple), values=Field) if self._base_initialized: for field in fields: - if field not in self.output_fields.keys(): + if ((field not in self.output_fields) and \ + (field not in self.output_tensor_fields)): msg='Field {} is not an output field of operator {}.' msg=msg.format(field.name, self.name) raise RuntimeError(msg) else: - fields = self.output_fields.keys() + fields = self.all_output_fields fields = list(sorted(fields, key=lambda f:f.name)) if (io_params is None): diff --git a/hysop/defaults.py b/hysop/defaults.py index 15423fc3b..7585c2ad3 100644 --- a/hysop/defaults.py +++ b/hysop/defaults.py @@ -2,5 +2,5 @@ from hysop.fields.default_fields import VelocityField, VorticityField, \ DensityField, ViscosityField, \ LevelSetField, PenalizationField -from hysop.parameters.default_parameters import TimeParameters, \ +from hysop.parameters.default_parameters import TimeParameters, ViscosityParameter, \ EnstrophyParameter, KineticEnergyParameter, VolumicIntegrationParameter diff --git a/hysop/fields/discrete_field.py b/hysop/fields/discrete_field.py index 379f9a147..f87cb7a0b 100644 --- a/hysop/fields/discrete_field.py +++ b/hysop/fields/discrete_field.py @@ -387,6 +387,9 @@ class DiscreteScalarFieldView(DiscreteScalarFieldViewContainerI, TaggedObjectVie def _get_dfield(self): """Get the discrete field on which the view is.""" return self._dfield + def _get_field(self): + """Get the continuous field on which the view is.""" + return self._dfield._field def _get_topology_state(self): """Get the topology state of this view.""" return self._topology_state @@ -505,6 +508,7 @@ class DiscreteScalarFieldView(DiscreteScalarFieldViewContainerI, TaggedObjectVie return self._dfield._symbol dfield = property(_get_dfield) + field = property(_get_field) topology_state = property(_get_topology_state) is_read_only = property(_get_is_read_only) diff --git a/hysop/operator/adapt_timestep.py b/hysop/operator/adapt_timestep.py index 5a67b23d7..9b52f3555 100755 --- a/hysop/operator/adapt_timestep.py +++ b/hysop/operator/adapt_timestep.py @@ -339,7 +339,10 @@ class AdaptiveTimeStep(ComputationalGraphNodeGenerator): * This operator has no effect on input variables. """ base_kwds = first_not_None(base_kwds, {}) - super(AdaptiveTimeStep, self).__init__(**base_kwds) + super(AdaptiveTimeStep, self).__init__( + candidate_input_tensors=(), + candidate_output_tensors=(), + **base_kwds) # tuple of criterias used to compute dt self.criterias = {} diff --git a/hysop/operator/base/min_max.py b/hysop/operator/base/min_max.py index ac3c3a308..826e72ea0 100644 --- a/hysop/operator/base/min_max.py +++ b/hysop/operator/base/min_max.py @@ -43,7 +43,7 @@ class MinMaxFieldStatisticsBase(object): def make_param(k, quiet): return TensorParameter(name=names[k], pretty_name=pretty_names[k], dtype=field.dtype, shape=(nb_components,), quiet=quiet) - + names = { 'Fmin': '{}min'.format(pbasename), 'Fmax': '{}max'.format(pbasename), diff --git a/hysop/operator/tests/test_directional_advection.py b/hysop/operator/tests/test_directional_advection.py index c969f237a..3fc8723d2 100644 --- a/hysop/operator/tests/test_directional_advection.py +++ b/hysop/operator/tests/test_directional_advection.py @@ -58,7 +58,7 @@ class TestDirectionalAdvectionOperator(object): velocity_cfls = (0.62, 1.89) else: flt_types = (npw.float,) - time_integrators = (RK2,) + time_integrators = (Euler,) remesh_kernels = (Remesh.L4_2,) velocity_cfls = (1.89,) @@ -180,6 +180,8 @@ class TestDirectionalAdvectionOperator(object): try: dvin.initialize(self.__velocity_init, axes=axes) dsin.initialize(self.__scalar_init) + print dvin[0].data + print dvin[1].data _input = tuple(dsin.data[i].get().handle.copy() for i in xrange(dsin.nb_components)) S0 = dsin.integrate() @@ -203,6 +205,7 @@ class TestDirectionalAdvectionOperator(object): dxk = -Vi*(k+0)*dt() dsref.initialize(self.__scalar_init, offsets=dxk.tolist()) d = dsout.distance(dsref, p=2) + print d if npw.any(d > 1e-2): print dsout.print_with_ghosts() @@ -271,9 +274,9 @@ class TestDirectionalAdvectionOperator(object): self._test(dim=3, is_inplace=True) def perform_tests(self): - self.test_advec_1D_inplace() + #self.test_advec_1D_inplace() self.test_advec_2D_inplace() - self.test_advec_3D_inplace() + #self.test_advec_3D_inplace() #self.test_advec_1D_out_of_place() #self.test_advec_2D_out_of_place() @@ -284,7 +287,7 @@ class TestDirectionalAdvectionOperator(object): if __name__ == '__main__': import hysop TestDirectionalAdvectionOperator.setup_class(enable_extra_tests=False, - enable_debug_mode=False) + enable_debug_mode=True) test = TestDirectionalAdvectionOperator() diff --git a/hysop/parameters/default_parameters.py b/hysop/parameters/default_parameters.py index b6776362a..2e920f0c5 100644 --- a/hysop/parameters/default_parameters.py +++ b/hysop/parameters/default_parameters.py @@ -10,6 +10,15 @@ def TimeParameters(dtype=None, **kwds): dt = ScalarParameter('dt', dtype=dtype, **kwds) return (t, dt) +def ViscosityParameter(name=None, pretty_name=None, mu=False, **kwds): + if mu: + name = first_not_None(name, 'mu') + pretty_name = first_not_None(pretty_name, greak[11]) + else: + name = first_not_None(name, 'nu') + pretty_name = first_not_None(pretty_name, greak[12]) + return ScalarParameter(name=name, pretty_name=pretty_name, **kwds) + def EnstrophyParameter(name=None, pretty_name=None, **kwds): name = first_not_None(name, 'enstrophy') pretty_name = first_not_None(pretty_name, greak[5]) diff --git a/hysop/parameters/parameter.py b/hysop/parameters/parameter.py index 968c2889f..a27f41605 100644 --- a/hysop/parameters/parameter.py +++ b/hysop/parameters/parameter.py @@ -29,6 +29,8 @@ class Parameter(TaggedObject, VariableTag): name : string A name for the parameter. A parameter is uniquely identified by its name. + pretty_name : string + A pretty name for the parameter. parameter_types: type of array like of types Allowed types for the parameter. None is accepted only if allow_none is set to True. @@ -55,6 +57,8 @@ class Parameter(TaggedObject, VariableTag): parameter_types: Return allowed parameter types for this parameter. """ + check_instance(name, str) + check_instance(pretty_name, (str, unicode), allow_none=True) check_instance(allow_None, bool) check_instance(const, bool) if not isinstance(parameter_types, type): diff --git a/hysop/parameters/tensor_parameter.py b/hysop/parameters/tensor_parameter.py index b878721df..8ffdd2d0d 100644 --- a/hysop/parameters/tensor_parameter.py +++ b/hysop/parameters/tensor_parameter.py @@ -3,7 +3,7 @@ from hysop.deps import np, sm from hysop.constants import HYSOP_REAL from hysop.tools.types import check_instance, first_not_None from hysop.tools.numerics import is_signed, is_unsigned, is_fp, is_complex -from hysop.tools.sympy_utils import subscripts +from hysop.tools.sympy_utils import subscripts, SymbolicBase from hysop.parameters.parameter import Parameter class TensorParameter(Parameter): @@ -12,7 +12,8 @@ class TensorParameter(Parameter): that may change value as simulation advances. """ - def __new__(cls, name, shape, dtype=HYSOP_REAL, initial_value=None, + def __new__(cls, name, shape, dtype=HYSOP_REAL, + pretty_name=None, initial_value=None, min_value=None, max_value=None, ignore_nans=False, **kwds): """ Create or get an existing TensorParameter with a specific name @@ -22,6 +23,8 @@ class TensorParameter(Parameter): ---------- name: string A name for the parameter that uniquely identifies it. + pretty_name: string + A pretty name for the parameter. shape: array like of ints Shape of this TensorParameter. dtype: type convertible to np.dtype, optional @@ -56,13 +59,18 @@ class TensorParameter(Parameter): if ('allow_None' in kwds) and (kwds['allow_None'] is True): msg='A TensorParameter cannot be allowed to be set to None.' raise ValueError(msg) + + check_instance(name, (str, SymbolicBase)) - if not isinstance(name, (str, unicode)): - symbol = name - name = symbol.name + if isinstance(name, SymbolicBase): + symbol = name + name = symbol._name + pretty_name = symbol._pretty_name else: symbol = None - check_instance(name, (str, unicode)) + pretty_name = first_not_None(pretty_name, name) + check_instance(name, str) + check_instance(pretty_name, (str, unicode)) check_instance(shape, (list,tuple), values=(int,long,np.integer)) check_instance(ignore_nans, bool) assert (min_value is None) or (max_value is None) or (min_value <= max_value) @@ -99,7 +107,8 @@ class TensorParameter(Parameter): elif is_complex(dtype): parameter_types += ( np.complex64, np.complex128, np.clongdouble, complex ) - obj = super(TensorParameter,cls).__new__(cls, name=name, + obj = super(TensorParameter,cls).__new__(cls, + name=name, pretty_name=pretty_name, parameter_types=parameter_types, allow_None=False, initial_value=initial_value, **kwds) diff --git a/hysop/problem.py b/hysop/problem.py index e9974db30..cf27415a6 100644 --- a/hysop/problem.py +++ b/hysop/problem.py @@ -47,25 +47,28 @@ class Problem(ComputationalGraph): op.output_discrete_fields, op.output_discrete_tensor_fields): if (field in op_fields): dfield = op_fields[field] - if dfield.has_unique_topology(): + if all((df in initialized) for df in dfield.discrete_fields()): + continue + elif dfield.has_unique_topology() and \ + all((df not in initialized) for df in dfield.discrete_fields()): topo_view = dfield.topology - topo = topo_view.topology - wstate = topo_view.topology_state.copy(is_read_only=False) # get a writtable state + topo = topo_view.topology + wstate = topo_view.topology_state.copy(is_read_only=False) # get a writtable state dfield = field.discretize(topo, wstate) dfield.initialize(**kwds) - initialized.add(*dfield.discrete_fields) + initialized.update(dfield.discrete_fields()) else: - print dfield for (component, dfield_i) in dfield.nd_iter(): - print dfield_i, type(dfield_i) + if (dfield_i._dfield in initialized): + continue topo_view = dfield_i.topology topo = topo_view.topology wstate = topo_view.topology_state.copy(is_read_only=False) # get a writtable state - dfield_i = field.discretize(topo, wstate) + dfield_i = dfield_i.field.discretize(topo, wstate) dfield_i.initialize(component=component, **kwds) initialized.add(dfield_i._dfield) if not initialized: - msg='Could not initialize field {}.'.format(field.name) + msg='FATAL ERROR: Could not initialize field {}.'.format(field.name) raise RuntimeError(msg) @debug diff --git a/hysop/symbolic/__init__.py b/hysop/symbolic/__init__.py index 1f004bdaa..33001022f 100644 --- a/hysop/symbolic/__init__.py +++ b/hysop/symbolic/__init__.py @@ -17,25 +17,33 @@ time_symbol = TimeSymbol('t') dtime_symbol = TimeSymbol('dt') """Dummy symbol representing infinitesimal time.""" -space_symbols = tuple(SpaceSymbol(name=u'x'+subscript(i), +space_symbols = tuple(SpaceSymbol( + name='x{}'.format(i), + pretty_name=u'x'+subscript(i), var_name='x{}'.format(i), latex_name='x_{{{}}}'.format(i)) for i in xrange(16)) """Dummy symbols representing space.""" -dspace_symbols = tuple(SpaceSymbol(name=u'dx'+subscript(i), +dspace_symbols = tuple(SpaceSymbol( + name='dx_{}'.format(i), + pretty_name=u'dx'+subscript(i), var_name='dx_{}'.format(i), latex_name='dx_{{{}}}'.format(i)) for i in xrange(16)) """Dummy symbols representing space infinitesimals.""" -local_indices_symbols = tuple(SpaceSymbol(name=u'i'+subscript(i), +local_indices_symbols = tuple(SpaceSymbol( + name = 'i{}'.format(i), + pretty_name=u'i'+subscript(i), var_name='i{}'.format(i), latex_name='i_{{{}}}'.format(i)) for i in xrange(16)) """Dummy symbols local array indices.""" -global_indices_symbols = tuple(SpaceSymbol(name=u'i'+subscript(i), +global_indices_symbols = tuple(SpaceSymbol( + name = 'I{}'.format(i), + pretty_name=u'I'+subscript(i), var_name='I{}'.format(i), latex_name='I_{{{}}}'.format(i)) for i in xrange(16)) diff --git a/hysop/symbolic/base.py b/hysop/symbolic/base.py index 05a4e7e53..2e8f9a30c 100644 --- a/hysop/symbolic/base.py +++ b/hysop/symbolic/base.py @@ -135,7 +135,9 @@ class TensorBase(npw.ndarray): vsep = '_' with obj.write_context(): for idx in npw.ndindex(*shape): - pname = u'{}{}'.format(pretty_name, u''.join(subscript(i) + name = '{}_{}'.format(name, vsep.join(str(i) + for i in idx)) + pname = u'{}{}'.format(pretty_name.decode('utf-8'), u''.join(subscript(i) for i in idx)) vname = '{}_{}'.format(name, vsep.join(str(i) for i in idx)) @@ -151,8 +153,12 @@ class TensorBase(npw.ndarray): assert k not in scalar_kwds, msg idx_kwds.update(scalar_kwds) skwds = idx_kwds - obj[idx] = scalar_cls(name=pname, var_name=vname, latex_name=lname, - value=value, idx=idx, **skwds) + obj[idx] = scalar_cls(name=name, + pretty_name=pname, + var_name=vname, + latex_name=lname, + value=value, idx=idx, + **skwds) else: obj[...] = init return obj diff --git a/hysop/symbolic/parameter.py b/hysop/symbolic/parameter.py index ab24726da..68a45ddcc 100644 --- a/hysop/symbolic/parameter.py +++ b/hysop/symbolic/parameter.py @@ -4,14 +4,14 @@ from hysop.tools.types import check_instance, to_tuple, first_not_None from hysop.tools.numpywrappers import npw class SymbolicTensorParameter(SymbolicTensor): - def __new__(cls, parameter, name=None, value=None, - shape=None, scalar_cls=None, **kwds): + def __new__(cls, parameter, name=None, pretty_name=None, + value=None, shape=None, scalar_cls=None, **kwds): from hysop.parameters.tensor_parameter import TensorParameter check_instance(parameter, TensorParameter) value = first_not_None(value, parameter) shape = first_not_None(shape, parameter.shape) - name = first_not_None(name, parameter.name) - pname = parameter.pretty_name.decode('utf-8') + name = first_not_None(name, parameter.name) + pname = first_not_None(pretty_name, parameter.pretty_name) scalar_cls = first_not_None(scalar_cls, SymbolicScalarParameter) scalar_kwds = dict(parameter=parameter) def make_scalar_kwds(idx): @@ -23,15 +23,15 @@ class SymbolicTensorParameter(SymbolicTensor): scalar_kwds=scalar_kwds, **kwds) class SymbolicScalarParameter(SymbolicScalar): - def __new__(cls, parameter, name=None, value=None, **kwds): + def __new__(cls, parameter, name=None, pretty_name=None, value=None, **kwds): from hysop.parameters.tensor_parameter import TensorParameter check_instance(parameter, TensorParameter) value = first_not_None(value, parameter._value) name = first_not_None(name, parameter.name) - pname = parameter.pretty_name.decode('utf-8') + pname = first_not_None(pretty_name, parameter.pretty_name) obj = super(SymbolicScalarParameter, cls).__new__(cls, name=name, pretty_name=pname, - value=value,**kwds) + value=value, **kwds) obj.parameter = parameter return obj diff --git a/hysop/tools/sympy_utils.py b/hysop/tools/sympy_utils.py index 9813d6576..d01814214 100644 --- a/hysop/tools/sympy_utils.py +++ b/hysop/tools/sympy_utils.py @@ -1,6 +1,6 @@ from hysop.deps import np, sm, copy -from hysop.tools.types import first_not_None +from hysop.tools.types import first_not_None, check_instance from sympy.utilities import group from sympy.printing.str import StrPrinter, StrReprPrinter @@ -58,9 +58,16 @@ def enable_pretty_printing(): class SymbolicBase(object): def __new__(cls, name, var_name=None, latex_name=None, pretty_name=None, **kwds): - name = name.encode('utf-8') + if isinstance(pretty_name, unicode): + pretty_name = pretty_name.encode('utf-8') + if isinstance(latex_name, unicode): + latex_name = latex_name.encode('utf-8') + check_instance(name, str) + check_instance(var_name, str, allow_none=True) + check_instance(latex_name, str, allow_none=True) + check_instance(pretty_name, str, allow_none=True) obj = super(SymbolicBase, cls).__new__(cls, name=name, **kwds) - obj._name = name + obj._name = name obj._var_name = first_not_None(var_name, name) obj._latex_name = first_not_None(latex_name, name) obj._pretty_name = first_not_None(pretty_name, name) diff --git a/hysop/tools/types.py b/hysop/tools/types.py index 4a4a1c55d..3236cb00c 100644 --- a/hysop/tools/types.py +++ b/hysop/tools/types.py @@ -68,6 +68,8 @@ def check_instance(val, cls, allow_none=False, **kargs): ', ...' if (len(val)>5) else '') except: types = type(val) + if isinstance(val, unicode): + val = val.encode('utf-8') msg='\nFATAL ERROR: Type did not match any of types {} for the following value:\n{}\n' msg+='which is of type {}.\n' msg=msg.format(all_cls, val, types) -- GitLab