def _write_to_pvd_file(fun, directory, filename, suffix, components=None): if components is not None: filename = filename + "_component_" + "".join(components) fun_rank = fun.value_rank() fun_dim = product(fun.value_shape()) assert fun_rank <= 2 if ((fun_rank is 1 and fun_dim not in (2, 3)) or (fun_rank is 2 and fun_dim not in (4, 9))): funs = fun.split(deepcopy=True) for (i, fun_i) in enumerate(funs): if components is not None: filename_i = filename + "_subcomponent_" + str(i) else: filename_i = filename + "_component_" + str(i) _write_to_pvd_file(fun_i, directory, filename_i, suffix) else: full_filename = os.path.join(str(directory), filename + ".pvd") if suffix is not None: if full_filename in _all_pvd_files: assert _all_pvd_latest_suffix[full_filename] == suffix - 1 _all_pvd_latest_suffix[full_filename] = suffix else: assert suffix == 0 _all_pvd_files[full_filename] = File(full_filename, "compressed") _all_pvd_latest_suffix[full_filename] = 0 _all_pvd_functions[full_filename] = fun.copy(deepcopy=True) # Make sure to always use the same function, otherwise dolfin # changes the numbering and visualization is difficult in ParaView assign(_all_pvd_functions[full_filename], fun) _all_pvd_files[full_filename] << _all_pvd_functions[full_filename] else: file_ = File(full_filename, "compressed") file_ << fun
def save_results_wrapper(PROJECT_ROOT, subFolder, u, p, w, subdomains, boundaries): velocityVisuPath = os.path.join(PROJECT_ROOT, 'src', 'Results', subFolder, 'Visualization', 'velocity.pvd') File(velocityVisuPath) << u pressureVisuPath = os.path.join(PROJECT_ROOT, 'src', 'Results', subFolder, 'Visualization', 'pressure.pvd') File(pressureVisuPath) << p resultsH5Path = os.path.join(PROJECT_ROOT, 'Results', subFolder, 'solution.h5') save_results_hdf5(resultsH5Path, subdomains, boundaries, w)
def save_meshfiles_wrapper(PROJECT_ROOT, subFolder, mesh, subdomains, boundaries): filePath = os.path.join(PROJECT_ROOT, 'src', 'MeshFiles', 'mesh.h5') mesh_to_h5(filePath, mesh, subdomains, boundaries) meshVisuPath = os.path.join(PROJECT_ROOT, 'src', 'MeshFiles', subFolder, 'Visualization', 'mesh.pvd') File(meshVisuPath) << mesh sudomainsVisuPath = os.path.join(PROJECT_ROOT, 'src', 'MeshFiles', subFolder, 'Visualization', 'subdomains.pvd') File(sudomainsVisuPath) << subdomains boundariesVisuPath = os.path.join(PROJECT_ROOT, 'src', 'MeshFiles', subFolder, 'Visualization', 'boundaries.pvd') File(boundariesVisuPath) << boundaries
def store_parameters(parameters): "Store parameters to file and return filename" # Save to file application_parameters.xml file = File("application_parameters.xml") file << parameters # Save to file <output_directory>/application_parameters.xml filename = "%s/application_parameters.xml" % parameters["output_directory"] file = File(filename) file << parameters return filename
def __init__(self, meshes, facetfunctions, cover_points, bc_dict, move_dict, length_width): """ Solve the stokes problem with multiple meshes. Arguments: meshes: List of dolfin meshes, in the order they should be added to the multimesh facetfunctions: List of FacetFunctions corresponding to the meshes above cover_points: dict where the key is the mesh that should get covered cells, value is at which point auto_cover should start bc_dict: Dictionary describing boundary conditions for the Stokes problem move_dict: Dictionary describing which node that will be fixed and which are design variables in the optimization problem length_width: List containing the length and width of channel without an obstacle. Needed to compute barycenter of obstacle """ self.__init_multimesh(meshes, cover_points) self.mfs = facetfunctions self.move_dict = move_dict self.V2 = VectorElement("CG", meshes[0].ufl_cell(), 2) self.S1 = FiniteElement("CG", meshes[0].ufl_cell(), 1) self.VQ = MultiMeshFunctionSpace(self.multimesh, self.V2 * self.S1) V = MultiMeshFunctionSpace(self.multimesh, self.V2) Q = MultiMeshFunctionSpace(self.multimesh, self.S1) self.__init_bcs(bc_dict) self.w = MultiMeshFunction(self.VQ, name="State") self.u = MultiMeshFunction(V, name="u") self.p = MultiMeshFunction(Q, name="p") self.f = Constant([0.] * self.multimesh.part(0).geometric_dimension()) self.N = len(meshes) self.backup = [ self.multimesh.part(i).coordinates().copy() for i in range(1, self.N) ] self.outu = [File("output/u_%d.pvd" % i) for i in range(self.N)] self.outp = [File("output/p_%d.pvd" % i) for i in range(self.N)] self.J = 0 self.dJ = 0 self.opt_it = 0 self.vfac = 5e4 self.bfac = 5e4 self.length_width = length_width self.__init_geometric_quantities()
def solve(self, opt): """ This procedure implements a first-order semi-Lagrangian time-stepping scheme to solve a parabolic second-order HJB equation in non-variational form - du/dt - sup_gamma{a^gamma : D^2 u + b^gamma * D u + c^gamma * u - f^gamma}= 0 """ if hasattr(self, 'dt'): opt["timeSteps"] *= opt["timeStepFactor"] nt = opt["timeSteps"] nc = len(self.gamma) Tspace = np.linspace(self.T[1], self.T[0], nt + 1) self.dt = (self.T[1] - self.T[0]) / nt self.u_np1 = Function(self.V) print('Setting final time conditions') assign(self.u, project(self.u_T, self.V)) if opt["saveSolution"]: file_u = File('./pvd/u.pvd') file_gamma = [] for i in range(nc): file_gamma.append(File('./pvd/gamma_{}.pvd'.format(i))) for i, s in enumerate(Tspace[1:]): self.current_time = s print('Iteration {}/{}:\t t = {}'.format(i + 1, nt, s)) self.iter = i # Update time in coefficient functions self.updateTime(s) assign(self.u_np1, self.u) # Solve problem for current time step super().solve(opt) # self.plotControl() # self.plotSolution() if opt["saveSolution"]: file_u << self.u for i in range(nc): try: file_gamma[i] << self.gamma[i] except AttributeError: file_gamma[i] << project(self.gamma[i], self.controlSpace[i])
def __init__(self, mesh, mf, bc_dict, move_dict): """ Inititalize Stokes solver with a mesh, its corresponding facet function, a dictionary describing boundary conditions and a dictionary describing which boundaries are fixed in the shape optimization setting """ self.mesh = mesh self.backup = mesh.coordinates().copy() self.mf = mf V2 = VectorElement("CG", mesh.ufl_cell(), 2) S1 = FiniteElement("CG", mesh.ufl_cell(), 1) TH = V2 * S1 self.VQ = FunctionSpace(self.mesh, TH) self.w = Function(self.VQ) self.f = Constant([0.]*mesh.geometric_dimension()) self.S = VectorFunctionSpace(self.mesh, "CG", 1) self.move_dict = move_dict self.J = 0 self._init_bcs(bc_dict) self.solve() self.vfac = 1e4 self.bfac = 1e2 self._init_geometric_functions() self.eval_current_J() self.eval_current_dJ() self.outfile = File("output/u_singlemesh.pvd") self.outfile << self.u self.gradient_scale = 1 self.iteration_counter = 1 self.create_mapping_for_moving_boundary()
def plot_vtk(self, variable, index=0): """Plot variable in vtk file given by filename""" self._check_outdir() self._check_varname() fname = self.varname + '_{0}'.format(index) File(self.outdir + fname + '.pvd') << variable (self.indices).append(index)
def setOutputPath(self, outputPath): """Set outut directory for saving the function state. Usually is done automatically by the simulator. Args: outputPath(:obj:`str`): A path to the output directory. """ self.file = File( os.path.join(outputPath, "{0}.pvd".format(self.userName) ))
def test_ect_current(): """Test that the Neumann BC on the extracellular potential is applied correctly.""" time = Constant(0) T = 1e-1 dt = 1e-5 mesh = UnitSquareMesh(75, 75) ect_current = Expression( "std::abs(sin(2*pi*70*t)) > 0.8 ? 800*(x[0] < 0.5 && x[1] < 0.5)*(t < t0) : 0", t=time, t0=10, degree=1) model = Wei() brain = CardiacModel(mesh, time, 0.1, 0.3, model, ect_current=ect_current) params = SplittingSolver.default_parameters() ps = SplittingSolver.default_parameters() ps["pde_solver"] = "bidomain" # TODO: parametrise mono/bi ps["BidomainSolver"]["linear_solver_type"] = "direct" ps["theta"] = 0.5 # TODO: parametrise theta solver = SplittingSolver(brain, params=ps) vs_, vs, _ = solver.solution_fields() assert False, "Use the other weimodel initial conditions." vs_.assign(model.initial_conditions()) solutions = solver.solve((0, T), dt) outfile = File("ect_testdir/v.pvd") counter = 0 for interval, (vs_, vs, _) in solutions: print(counter) v, *_ = vs.split() outfile << v counter += 1
def as_pvd(h5_file): '''Store facet and cell function for pvd''' root, ext = os.path.splitext(h5_file) mesh = Mesh() hdf = HDF5File(mesh.mpi_comm(), h5_file, 'r') hdf.read(mesh, '/mesh', False) facet_markers = FacetFunction('size_t', mesh) hdf.read(facet_markers, '/facet_markers') cell_markers = CellFunction('size_t', mesh) hdf.read(cell_markers, '/cell_markers') File(root + 'facets' + '.pvd') << facet_markers File(root + 'volumes' + '.pvd') << cell_markers return True
def build(self, accuracy=5, cache=False): if cache and os.path.exists(self._cache_path): self._mesh2d = DolfinMesh(self._cache_path) return self._mesh2d = mshr.generate_mesh(self._map, accuracy) if cache: f = File(self._cache_path) f << self._mesh2d
def Save(self, func, filename, subfolder="",val=0,file=None,filetype="default"): """ This function is used to save the various dolfin.Functions created by windse. It should only be accessed internally. Args: func (dolfin.Function): The Function to be saved filename (str): the name of the function :Keyword Arguments: * **subfolder** (*str*): where to save the files within the output folder * **n** (*float*): used for saving a series of output. Use n=0 for the first save. """ self.fprint("Saving: {0}".format(filename)) ### Name the function in the meta data, This should probably be done at creation func.rename(filename,filename) if filetype == "default": filetype = self.save_file_type if file is None: ### Make sure the folder exists if not os.path.exists(self.folder+subfolder): os.makedirs(self.folder+subfolder) if filetype == "pvd": file_string = self.folder+subfolder+filename+".pvd" out = File(file_string) out << (func,val) elif filetype == "xdmf": file_string = self.folder+subfolder+filename+".xdmf" out = XDMFFile(file_string) out.write(func,val) return out else: if filetype == "pvd" or isinstance(func,type(Mesh)): file << (func,val) elif filetype == "xdmf": file.write(func,val)
def store_parameters(p, problem, case): "Store parameters to file and return filename" # Set output directory if p["output_directory"] == "unspecified": if case is None: p["output_directory"] = "results-%s-%s" % (problem, date()) else: p["output_directory"] = "results-%s-%s" % (problem, str(case)) # Save to file application_parameters.xml file = File("application_parameters.xml") file << p # Save to file <output_directory>/application_parameters.xml filename = "%s/application_parameters.xml" % p["output_directory"] file = File(filename) file << p return filename
def savingPreparation(paraFullPath, ParaViewFilenames): from dolfin import File # Create New Result Files (Paraview Files: .pvd) fileNames = [] paraFiles = [] for i in range(0, len( ParaViewFilenames)): # ParaViewFilenames defined in Problem Imputs fileNames.append(ParaViewFilenames[i] + ".pvd") paraFiles.append(File(paraFullPath + fileNames[i])) return paraFiles
def write(self, comm, filename="muflon-parameters.xml"): """ Write parameters to XML file. :param comm: MPI communicator :type comm: :py:class:`dolfin.MPI_Comm` :param filename: name of the output XML file (can be relative or absolute path) :type filename: str """ filename += ".xml" if filename[-4:] != ".xml" else "" log(DEBUG, "Writing current parameter values into '%s'." % filename) from dolfin import DOLFIN_VERSION_MAJOR, DOLFIN_VERSION_MINOR if DOLFIN_VERSION_MAJOR >= 2017 and DOLFIN_VERSION_MINOR >= 2: with File(filename) as xmlfile: xmlfile << self elif MPI.rank(comm) == 0: # FIXME: remove this backporting with File(filename) as xmlfile: xmlfile << self else: return
def _read_from_xml_file(fun, directory, filename, suffix): if suffix is not None: filename = filename + "." + str(suffix) full_filename = os.path.join(str(directory), filename + ".xml") file_exists = False if is_io_process() and os.path.exists(full_filename): file_exists = True file_exists = is_io_process.mpi_comm.bcast(file_exists, root=is_io_process.root) if file_exists: file_ = File(full_filename) file_ >> fun return file_exists
def _update_pvd_file(self, field_name, saveformat, data, timestep, t): "Update pvd file with new data." assert isinstance(data, Function) assert saveformat == "pvd" fullname, metadata = self._get_datafile_name(field_name, saveformat, timestep) key = (field_name, saveformat) datafile = self._datafile_cache.get(key) if datafile is None: datafile = File(fullname) self._datafile_cache[key] = datafile datafile << data return metadata
def _update_xml_gz_file(self, field_name, saveformat, data, timestep, t): "Create new xml.gz file for current timestep with new data." assert saveformat == "xml.gz" fullname, metadata = self._get_datafile_name(field_name, saveformat, timestep) meshfile = os.path.join(self.get_savedir(field_name), "mesh.hdf5") if not os.path.isfile(meshfile): hdf5file = HDF5File(mpi_comm_world(), meshfile, 'w') hdf5file.write(data.function_space().mesh(), "Mesh") del hdf5file datafile = File(fullname) datafile << data return metadata
def read(self, filename="muflon-parameters.xml"): """ Read parameters from XML file. :param filename: name of the input XML file (can be relative or absolute path) :type filename: str """ filename += ".xml" if filename[-4:] != ".xml" else "" if os.path.isfile(filename) and os.access(filename, os.R_OK): log(DEBUG, "Reading default values from '%s'" % filename) with File(filename) as xmlfile: xmlfile >> self else: log(DEBUG, "File '%s' is missing or not readable." % filename)
def read_parameters(): """Read parametrs from file specified on command-line or return default parameters if no file is specified""" # Read parameters from the command-line import sys p = default_parameters() try: file = File(sys.argv[1]) file >> p info("Parameters read from %s." % sys.argv[1]) except: info("No parameters specified, using default parameters.") # Set output directory if p["output_directory"] == "unspecified": p["output_directory"] = "results-%s" % date() # Save to file <output_directory>/application_parameters.xml filename = "%s/application_parameters.xml" % p["output_directory"] file = File(filename) file << p return p
def _export_vtk(self, solution, filename, output_options={}): if not "With mesh motion" in output_options: output_options["With mesh motion"] = False if not "With preprocessing" in output_options: output_options["With preprocessing"] = False # file = File(filename + ".pvd", "compressed") if output_options["With mesh motion"]: self.move_mesh() # deform the mesh if output_options["With preprocessing"]: preprocessed_solution = self.preprocess_solution_for_plot(solution) file << preprocessed_solution else: file << solution if output_options["With mesh motion"]: self.reset_reference() # undo mesh motion
def save_eigenvectors(self,n,file_name="output/modes.pvd",save_imaginary=False): eigenvalues = [] eigenvectors = [] file = File(self.comm,file_name) for i in range(n): eig, u_r, u_im = self.get_eigenpair(i) u_r.rename("mode real","mode real") file.write(u_r,i) if save_imaginary: u_im.rename("mode imaginary","mode imaginary") file.write(u_im,i) return file_name
def __init__(self, name, functionSpace0 = None, function = None, functionSpace = None): self.userName = name self.file = File(os.path.join( sys.path[0], "{0}.pvd".format(self.userName) )) if function: super().__init__(function.function_space(), function.vector()) elif functionSpace: super().__init__(functionSpace) else: raise Exception("Either function or functionSpace must be supplied.") self.functionSpace0 = None if functionSpace0: self.functionSpace0 = functionSpace0 self.initial = Function(functionSpace0, self.vector()) self.functionSpace = self.function_space()
def _write(self, filename, encoding=None): assert filename.endswith(".rtc.xml") or filename.endswith(".rtc.xdmf") # Create output folder try: os.makedirs(filename) except OSError: if not os.path.isdir(filename): raise # Write out MeshFunctions for (d, mesh_function_d) in enumerate(self): if filename.endswith(".rtc.xml"): File(filename + "/mesh_function_" + str(d) + ".xml") << mesh_function_d else: xdmf_file = XDMFFile(filename + "/mesh_function_" + str(d) + ".xdmf") if encoding is not None: xdmf_file.write(mesh_function_d, encoding) else: xdmf_file.write(mesh_function_d)
def exportU(self, Vh, fname, varname="evect", normalize=1): """ Export in paraview the generalized eigenvectors U. Inputs: - Vh: the parameter finite element space - fname: the name of the paraview output file - varname: the name of the paraview variable - normalize: if True the eigenvector are rescaled such that || u ||_inf = 1 """ evect = Function(Vh, name=varname) fid = File(fname) for i in range(0, self.U.shape[1]): Ui = self.U[:, i] if normalize: s = 1 / np.linalg.norm(Ui, np.inf) evect.vector().set_local(s * Ui) else: evect.vector().set_local(Ui) fid << evect
def create_output(self, fname): args = self.args parameters = self.parameters self.signature = hashlib.md5( str(parameters).encode('utf-8')).hexdigest() print('Signature is: ', self.signature) regime = self.p if args.outdir == None: outdir = "output/{:s}-{}{}".format(fname, self.signature, args.postfix) else: outdir = args.outdir self.outdir = outdir Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: ', outdir) print('Output in: ', os.path.join(outdir, fname + 'p-' + regime + '.xdmf')) print('P-proc in: ', os.path.join(outdir, fname + 'p-' + regime + '_pproc.xdmf')) file_results = XDMFFile( os.path.join(outdir, fname + 'p-' + regime + '.xdmf')) file_results.parameters["flush_output"] = True file_results.parameters["functions_share_mesh"] = True file_pproc = XDMFFile( os.path.join(outdir, fname + 'p-' + regime + '_pproc.xdmf')) file_pproc.parameters["flush_output"] = True file_pproc.parameters["functions_share_mesh"] = True file_mesh = File( os.path.join(outdir, fname + 'p-' + regime + "_mesh.xml")) with open(os.path.join(outdir, 'parameters.pkl'), 'w') as f: json.dump(parameters, f) print('DEBUG: pproc file', os.path.join(outdir, fname + 'p-' + regime + '_pproc.xdmf')) return file_results, file_pproc, file_mesh
def solve(self, opt): """ This procedure implements a first-order semi-Lagrangian time-stepping scheme to solve a parabolic second-order PDE in non-variational form - du/dt - (a : D^2 u + b * D u + c * u ) = - f <==> - du/dt - (a : D^2 u + b * D u + c * u - f ) = 0 """ if hasattr(self, 'dt'): opt["timeSteps"] *= opt["timeStepFactor"] nt = opt["timeSteps"] Tspace = np.linspace(self.T[1], self.T[0], nt + 1) self.dt = (self.T[1] - self.T[0]) / nt self.u_np1 = Function(self.V) if opt["saveSolution"]: file_u = File('./pvd/u.pvd') print('Setting final time conditions') assign(self.u, project(self.u_T, self.V)) if opt["saveSolution"]: file_u << self.u for i, s in enumerate(Tspace[1:]): print('Iteration {}/{}:\t t = {}'.format(i + 1, nt, s)) self.iter = i # Update time in coefficient functions self.updateTime(s) assign(self.u_np1, self.u) # Solve problem for current time step super().solve(opt) if opt["saveSolution"]: file_u << self.u
def export(self, Vh, filename, varname="mv", normalize=False): """ Export in paraview this multivector Inputs: - Vh: the parameter finite element space - filename: the name of the paraview output file - varname: the name of the paraview variable - normalize: if True the vector are rescaled such that || u ||_inf = 1 """ fid = File(filename) if not normalize: for i in range(self.nvec()): fun = vector2Function(self[i], Vh, name=varname) fid << fun else: tmp = self[0].copy() for i in range(self.nvec()): s = self[i].norm("linf") tmp.zero() tmp.axpy(1. / s, self[i]) fun = vector2Function(tmp, Vh, name=varname) fid << fun
def collect_timings(outdir, tic): # list_timings(TimingClear.keep, [TimingType.wall, TimingType.system]) # t = timings(TimingClear.keep, [TimingType.wall, TimingType.user, TimingType.system]) t = timings(TimingClear.keep, [TimingType.wall]) # Use different MPI reductions t_sum = MPI.sum(MPI.comm_world, t) # t_min = MPI.min(MPI.comm_world, t) # t_max = MPI.max(MPI.comm_world, t) t_avg = MPI.avg(MPI.comm_world, t) # Print aggregate timings to screen print('\n' + t_sum.str(True)) # print('\n'+t_min.str(True)) # print('\n'+t_max.str(True)) print('\n' + t_avg.str(True)) # Store to XML file on rank 0 if MPI.rank(MPI.comm_world) == 0: f = File(MPI.comm_self, os.path.join(outdir, "timings_aggregate.xml")) f << t_sum # f << t_min # f << t_max f << t_avg dump_timings_to_xml(os.path.join(outdir, "timings_avg_min_max.xml"), TimingClear.clear) elapsed = time.time() - tic comm = mpi4py.MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() if rank == 0: with open(os.path.join(outdir, 'timings.pkl'), 'w') as f: json.dump({'elapsed': elapsed, 'size': size}, f) pass