def run_simulation( filepath, topology_info: int = None, top_bc: int = None, bot_bc: int = None, left_bc: int = None, right_bc: int = None, geometry: dict = None, kappa=3, #only if geometry is None show=True, save_solution=False): from dolfin import (Mesh, XDMFFile, MeshValueCollection, cpp, FunctionSpace, TrialFunction, TestFunction, DirichletBC, Constant, Measure, inner, nabla_grad, Function, solve, plot, File) mesh = Mesh() with XDMFFile("%s_triangle.xdmf" % filepath.split('.')[0]) as infile: infile.read(mesh) # read the complete mesh mvc_subdo = MeshValueCollection("size_t", mesh, mesh.geometric_dimension() - 1) with XDMFFile("%s_triangle.xdmf" % filepath.split('.')[0]) as infile: infile.read(mvc_subdo, "subdomains") # read the diferent subdomians subdomains = cpp.mesh.MeshFunctionSizet(mesh, mvc_subdo) mvc = MeshValueCollection("size_t", mesh, mesh.geometric_dimension() - 2) with XDMFFile("%s_line.xdmf" % filepath.split('.')[0]) as infile: infile.read(mvc, "boundary_conditions") #read the boundary conditions boundary = cpp.mesh.MeshFunctionSizet(mesh, mvc) # Define function space and basis functions V = FunctionSpace(mesh, "CG", 1) u = TrialFunction(V) v = TestFunction(V) # Boundary conditions bcs = [] for bc_id in topology_info.keys(): if bc_id[-2:] == "bc": if bot_bc is not None and bc_id[:3] == "bot": bcs.append( DirichletBC(V, Constant(bot_bc), boundary, topology_info[bc_id])) elif left_bc is not None and bc_id[:4] == "left": bcs.append( DirichletBC(V, Constant(left_bc), boundary, topology_info[bc_id])) elif top_bc is not None and bc_id[:3] == "top": bcs.append( DirichletBC(V, Constant(top_bc), boundary, topology_info[bc_id])) elif right_bc is not None and bc_id[:5] == "right": bcs.append( DirichletBC(V, Constant(right_bc), boundary, topology_info[bc_id])) else: print(bc_id + " Not assigned as boundary condition ") # raise NotImplementedError # Define new measures associated with the interior domains and # exterior boundaries dx = Measure("dx", subdomain_data=subdomains) ds = Measure("ds", subdomain_data=boundary) f = Constant(0) g = Constant(0) if geometry is not None: # run multipatch implementation (Multiple domains) a = [] L = [] for patch_id in geometry.keys(): kappa = geometry[patch_id].get("kappa") a.append( inner(Constant(kappa) * nabla_grad(u), nabla_grad(v)) * dx(topology_info[patch_id])) L.append(f * v * dx(topology_info[patch_id])) a = sum(a) L = sum(L) else: a = inner(Constant(kappa) * nabla_grad(u), nabla_grad(v)) * dx L = f * v * dx ## Redefine u as a function in function space V for the solution u = Function(V) # Solve solve(a == L, u, bcs) u.rename('u', 'Temperature') # Save solution to file in VTK format print(' [+] Output to %s_solution.pvd' % filepath.split('.')[0]) vtkfile = File('%s_solution.pvd' % filepath.split('.')[0]) vtkfile << u if show: import matplotlib matplotlib.use("Qt5Agg") # Plot solution and gradient plot(u, title="Temperature") plt.gca().view_init(azim=-90, elev=90) plt.show() dofs = V.tabulate_dof_coordinates().reshape( V.dim(), mesh.geometry().dim()) #coordinates of nodes vals = u.vector().get_local() #temperature at nodes if save_solution: from dolfin import HDF5File, MPI output_file = HDF5File(MPI.comm_world, filepath.split('.')[0] + "_solution_field.h5", "w") output_file.write(u, "solution") output_file.close() u.set_allow_extrapolation(True) return dofs, vals, mesh, u