def _check_field(field, subfieldname, data=None, site=None): """ Internal function used to make some sanity checks before setting a field. """ # We do a number of sanity checks for which we need some metadata list_of_subfield_and_shape_tuples = nfem.data_doftypes(field) # Gets all the shapes mapped by the subfield names shape_by_subfieldname = {} for sfname, shape in list_of_subfield_and_shape_tuples: shape_by_subfieldname[sfname] = shape # 1 Does the field have this subfield: if subfieldname not in shape_by_subfieldname: subfields = shape_by_subfieldname.keys() msg = ("You want to set %s but I have only found subfield(s) '%s' " "in the field.%s" % (_set_what_msg(subfieldname, site), subfields, _data_msg(data))) raise NmagUserError(msg) # 2 Is the shape of the data right? shape = list(numpy.array(data).shape) # quite a silly way to get the # shape, but it works! if shape != shape_by_subfieldname[subfieldname]: msg = ("When trying to set %s we have a shape mismatch. The shape of " "the subfield data is '%s' but the shape of your data is '%s'." "%s" % (_set_what_msg(subfieldname, site), shape_by_subfieldname[subfieldname], shape, _data_msg(data))) raise NmagUserError(msg)
def _prepare_set_field(field, subfieldname, data, site=None, scale_factor=1.0, normalise=False, check_site=False): """ Internal function used to make some sanity checks before setting a field. """ # We do a number of sanity checks for which we need some metadata list_of_subfield_and_shape_tuples = nfem.data_doftypes(field) # Gets all the shapes mapped by the subfield names shape_by_subfieldname = {} for sfname, shape in list_of_subfield_and_shape_tuples: shape_by_subfieldname[sfname] = shape # 1 Does the field have this subfield: if not subfieldname in shape_by_subfieldname.keys(): subfields = shape_by_subfieldname.keys() msg = ("You want to set %s but I have only found subfield(s) '%s' " "in the field. By the way, your data is '%s'." % (_set_what_msg(subfieldname, site), subfields, data)) raise NmagUserError(msg) # 2 Is the shape of the data right? shape = list(numpy.array(data).shape) # quite a silly way to get the # shape, but it works! if shape != shape_by_subfieldname[subfieldname]: msg = ("When trying to set %s we have a shape mismatch. The shape of " "the subfield data is '%s' but the shape of your data is '%s'." "By the way, your data is '%s'." % (_set_what_msg(subfieldname, site), shape_by_subfieldname[subfieldname], shape, data)) raise NmagUserError(msg) # 3 is the data of the right type --> done by ocaml # 4 check that the site type is a list if check_site and type(site) != types.ListType: raise NmagUserError("'site' has to be a list of integers. For " "first order basis functions, there is only " "one integer in the list, the node id.") # Now we can actually set the data. # Do we need to normalise? if normalise: data = normalised_vector(data) # Do we need to apply the scale factor if type(data) in [types.IntType, types.FloatType, types.BooleanType]: data *= float(scale_factor) else: # FIXME: this doesn't work with tensors! data = map(lambda x : x*float(scale_factor), data) return data
def fields2vtkfile( fields, filename, mesh = None, only_dofname=None, format="binary",path=None,extrafields=None,header='Header (unused)'): """ def fields2vtkfile( fields, filename, mesh = None, only_dofname=None, format="ascii",path=None): Given a list of FIELDS (or just one field), a FILENAME and, optionally a MESH and some other values, this function goes through all degrees of freedoms in the field list and writes their data to the vtk file with name FILENAME. Currently, scalar and vector data on 2d and 3d meshes is supported. Optional extra arguments are: format : 'ascii' or 'binary' (how the data is stored in the vtk file) only_dofname: if a name for a degree of freedom (dof) is given here, then only the data for this dof is written to the vtk file. mesh : if not provided, the default mesh in nfem2 is chosen. If there is no default mesh defined, then a mesh needs to be provided here, or the function will report an error. path : if given, the file will be written no PATH/FILENAME. if path is not specified, the file will be written to the nfem default directory (nbase.run_dir) extrafields : if given, this needs to be a tuple of a fieldname and the data in Python lists. Example usage: providing the maxangle data """ filepath = nsim.snippets.output_file_location(filename,path) log.debug("Entering fields2vtkfile to write %s" % filepath) #check that fields are of the right type if type(fields) != type([]): fieldlist = [fields] else: fieldlist = fields if len(fieldlist) == 0: raise NfemValueError, "No field received" import ocaml if ocaml.sys_ocamlpill_type(fieldlist[0]) != 'FEM Field': raise NfemValueError, "Expect FEM Fields as input" #get the mesh (should check the type here, really.) if mesh == None: mesh=get_default_mesh() meshinfo = mesh.tolists() points = meshinfo[0][2] log.debug("Number of points in mesh=%d" % len(points)) tmp = meshinfo[2][2] simplices = map( lambda a: a[0], tmp) log.debug("Number of simplices in mesh=%d" % len(simplices)) #check dimensionality of the mesh if len(points[0])==2: log.debug("mesh is 2d") mesh_dim = 2 elif len(points[0])==3: log.debug("mesh is 3d") mesh_dim = 3 else: log.debug("mesh is 1d") mesh_dim = 1 log.warn("1d data is new -- may be buggy (fangohr 26/10/2006)") #assume that 'fieldlist' is a list of FEM fields. #First, create the following data structure. #dof_to_process = [field, dof, dim] dof_to_process = [] for field in fieldlist: #learn about dof in this field: content = nfem.data_doftypes(field) for dof in content: name, maxind = dof if only_dofname: if name != only_dofname: continue if len(maxind)>1: raise NfemValueError,"Can only deal with scalar and vector data at the moment (no tensor data)." if len(maxind)==0: dim = 1 #this is a scalar elif len(maxind)==1: if maxind[0] ==2: #this is a 2d vector dim = 2 elif maxind[0] ==3: #this is a 3d vector dim = 3 else: raise NfemValueError,"Can only process vectors in 2 and 3 dimensions" dof_to_process.append( (field, name, dim) ) log.debug("adding %s" % str(dof_to_process[-1]) ) #pyvtk requires us to create a vtk object and to give it the first #dof at that time. For all subsequent dofs, we can add them one by one. #check that we have some dofs to process: if len(dof_to_process)==0: raise NfemUserError,"Have not found any degrees of freedom (Maybe you have used only_dofname with a wrong name?)" names = str(map(lambda a : a[1], dof_to_process)) log.info("About to write field(s) '%s' to %s (%s)" % (names,filename,filepath)) #create vtk object with first data set field, name,dim = dof_to_process[0] data = _field2meshdata(len(points),field,name,dim) vtk = _vtk_createVtkData(points,simplices,data,name,header) log.log(15,"Adding %d-dim field %s to %s" % (dim,name,filename)) #and then process all others for dof in dof_to_process[1:]: field, name,dim = dof if only_dofname: if name!=only_dofname: continue log.debug("Adding %d-dim dof %s to %s" % (dim,name,filename)) data = _field2meshdata(len(points),field,name,dim) vtk = _vtk_addPointdata(vtk,data,name) #and process all extra fields (not nfem fields) if extrafields: for name, data in extrafields: if only_dofname: if name!=only_dofname: continue log.log(15,"Adding data %s to %s" % (name,filename)) #from IPython.Shell import IPShellEmbed #ipshell = IPShellEmbed() #ipshell() vtk = _vtk_addPointdata(vtk,data,name) vtk.tofile(filepath,format=format)
def fields2vtkfile(fields, filename, mesh=None, only_dofname=None, format="binary", path=None, extrafields=None, header='Header (unused)'): """ def fields2vtkfile( fields, filename, mesh = None, only_dofname=None, format="ascii",path=None): Given a list of FIELDS (or just one field), a FILENAME and, optionally a MESH and some other values, this function goes through all degrees of freedoms in the field list and writes their data to the vtk file with name FILENAME. Currently, scalar and vector data on 2d and 3d meshes is supported. Optional extra arguments are: format : 'ascii' or 'binary' (how the data is stored in the vtk file) only_dofname: if a name for a degree of freedom (dof) is given here, then only the data for this dof is written to the vtk file. mesh : if not provided, the default mesh in nfem2 is chosen. If there is no default mesh defined, then a mesh needs to be provided here, or the function will report an error. path : if given, the file will be written no PATH/FILENAME. if path is not specified, the file will be written to the nfem default directory (nbase.run_dir) extrafields : if given, this needs to be a tuple of a fieldname and the data in Python lists. Example usage: providing the maxangle data """ filepath = nsim.snippets.output_file_location(filename, path) log.debug("Entering fields2vtkfile to write %s" % filepath) #check that fields are of the right type if type(fields) != type([]): fieldlist = [fields] else: fieldlist = fields if len(fieldlist) == 0: raise NfemValueError, "No field received" import ocaml if ocaml.sys_ocamlpill_type(fieldlist[0]) != 'FEM Field': raise NfemValueError, "Expect FEM Fields as input" #get the mesh (should check the type here, really.) if mesh == None: mesh = get_default_mesh() meshinfo = mesh.tolists() points = meshinfo[0][2] log.debug("Number of points in mesh=%d" % len(points)) tmp = meshinfo[2][2] simplices = map(lambda a: a[0], tmp) log.debug("Number of simplices in mesh=%d" % len(simplices)) #check dimensionality of the mesh if len(points[0]) == 2: log.debug("mesh is 2d") mesh_dim = 2 elif len(points[0]) == 3: log.debug("mesh is 3d") mesh_dim = 3 else: log.debug("mesh is 1d") mesh_dim = 1 log.warn("1d data is new -- may be buggy (fangohr 26/10/2006)") #assume that 'fieldlist' is a list of FEM fields. #First, create the following data structure. #dof_to_process = [field, dof, dim] dof_to_process = [] for field in fieldlist: #learn about dof in this field: content = nfem.data_doftypes(field) for dof in content: name, maxind = dof if only_dofname: if name != only_dofname: continue if len(maxind) > 1: raise NfemValueError, "Can only deal with scalar and vector data at the moment (no tensor data)." if len(maxind) == 0: dim = 1 #this is a scalar elif len(maxind) == 1: if maxind[0] == 2: #this is a 2d vector dim = 2 elif maxind[0] == 3: #this is a 3d vector dim = 3 else: raise NfemValueError, "Can only process vectors in 2 and 3 dimensions" dof_to_process.append((field, name, dim)) log.debug("adding %s" % str(dof_to_process[-1])) #pyvtk requires us to create a vtk object and to give it the first #dof at that time. For all subsequent dofs, we can add them one by one. #check that we have some dofs to process: if len(dof_to_process) == 0: raise NfemUserError, "Have not found any degrees of freedom (Maybe you have used only_dofname with a wrong name?)" names = str(map(lambda a: a[1], dof_to_process)) log.info("About to write field(s) '%s' to %s (%s)" % (names, filename, filepath)) #create vtk object with first data set field, name, dim = dof_to_process[0] data = _field2meshdata(len(points), field, name, dim) vtk = _vtk_createVtkData(points, simplices, data, name, header) log.log(15, "Adding %d-dim field %s to %s" % (dim, name, filename)) #and then process all others for dof in dof_to_process[1:]: field, name, dim = dof if only_dofname: if name != only_dofname: continue log.debug("Adding %d-dim dof %s to %s" % (dim, name, filename)) data = _field2meshdata(len(points), field, name, dim) vtk = _vtk_addPointdata(vtk, data, name) #and process all extra fields (not nfem fields) if extrafields: for name, data in extrafields: if only_dofname: if name != only_dofname: continue log.log(15, "Adding data %s to %s" % (name, filename)) #from IPython.Shell import IPShellEmbed #ipshell = IPShellEmbed() #ipshell() vtk = _vtk_addPointdata(vtk, data, name) vtk.tofile(filepath, format=format)
#print "field_J contents:", nfem.data_doftypes(field_J) # XXX NOTE: we should be able to make an applicator that does the # cofield_to_field conversion automatically! # # # Next, let us compute the new condictivity by site-wise operation on # field_J. We just overwrite field_sigma: # recompute_conductivity([h_x,h_y,sigma0,alpha],fields=[the_field_sigma,field_J]) print "Refcount field_sigma:",ocaml.sys_refcount(the_field_sigma) return the_field_sigma for i in range(1,5): # was: range(1,5) update_sigma(field_sigma,i) print "Forcing ocaml GC!" sys.stdout.flush() ocaml.sys_check_heap() print "Iteration ",i," sigma at origin: ",nfem.probe_field(field_sigma,[0.0,0.0]) print "Current: ",compute_total_current(field_sigma) # nfem.field_print_contents( field_sigma) print "field_sigma contents:", nfem.data_doftypes(field_sigma) nfem.plot_scalar_field(field_sigma,"sigma","/tmp/sigma.ps", color_scheme=[(0.9,[0.2,0.2,1.0]),(1.0,[0.2,1.0,0.2]),(1.1,[1.0,1.0,0.2])])
def _prepare_set_field(field, subfieldname, data, site=None, scale_factor=1.0, normalise=False, check_site=False): """ Internal function used to make some sanity checks before setting a field. """ # We do a number of sanity checks for which we need some metadata list_of_subfield_and_shape_tuples = nfem.data_doftypes(field) # Gets all the shapes mapped by the subfield names shape_by_subfieldname = {} for sfname, shape in list_of_subfield_and_shape_tuples: shape_by_subfieldname[sfname] = shape # 1 Does the field have this subfield: if not subfieldname in shape_by_subfieldname.keys(): subfields = shape_by_subfieldname.keys() msg = ("You want to set %s but I have only found subfield(s) '%s' " "in the field. By the way, your data is '%s'." % (_set_what_msg(subfieldname, site), subfields, data)) raise NmagUserError(msg) # 2 Is the shape of the data right? shape = list(numpy.array(data).shape) # quite a silly way to get the # shape, but it works! if shape != shape_by_subfieldname[subfieldname]: msg = ("When trying to set %s we have a shape mismatch. The shape of " "the subfield data is '%s' but the shape of your data is '%s'." "By the way, your data is '%s'." % (_set_what_msg(subfieldname, site), shape_by_subfieldname[subfieldname], shape, data)) raise NmagUserError(msg) # 3 is the data of the right type --> done by ocaml # 4 check that the site type is a list if check_site and type(site) != types.ListType: raise NmagUserError("'site' has to be a list of integers. For " "first order basis functions, there is only " "one integer in the list, the node id.") # Now we can actually set the data. # Do we need to normalise? if normalise: data = normalised_vector(data) # Do we need to apply the scale factor if type(data) in [types.IntType, types.FloatType, types.BooleanType]: data *= float(scale_factor) else: # FIXME: this doesn't work with tensors! data = map(lambda x: x * float(scale_factor), data) return data
# # Next, let us compute the new condictivity by site-wise operation on # field_J. We just overwrite field_sigma: # recompute_conductivity([h_x, h_y, sigma0, alpha], fields=[the_field_sigma, field_J]) print "Refcount field_sigma:", ocaml.sys_refcount(the_field_sigma) return the_field_sigma for i in range(1, 5): # was: range(1,5) update_sigma(field_sigma, i) print "Forcing ocaml GC!" sys.stdout.flush() ocaml.sys_check_heap() print "Iteration ", i, " sigma at origin: ", nfem.probe_field( field_sigma, [0.0, 0.0]) print "Current: ", compute_total_current(field_sigma) # nfem.field_print_contents( field_sigma) print "field_sigma contents:", nfem.data_doftypes(field_sigma) nfem.plot_scalar_field(field_sigma, "sigma", "/tmp/sigma.ps", color_scheme=[(0.9, [0.2, 0.2, 1.0]), (1.0, [0.2, 1.0, 0.2]), (1.1, [1.0, 1.0, 0.2])])