def test_Probes_vectorfunctionspace_3D(VF3, dirpath): u0 = interpolate(Expression(('x[0]', 'x[1]', 'x[2]'), degree=1), VF3) x = array([[0.5, 0.5, 0.5], [0.4, 0.4, 0.4], [0.3, 0.3, 0.3]]) p = Probes(x.flatten(), VF3) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(MPI.comm_world) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 2] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(MPI.comm_world) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 2] - 0.3, 7) == 0 p0 = p.array(filename=dirpath+'dumpvector3D') if MPI.rank(MPI.comm_world) == 0: assert round(p0[0, 0, 0] - 0.5, 7) == 0 assert round(p0[1, 1, 0] - 0.4, 7) == 0 assert round(p0[2, 1, 0] - 0.3, 7) == 0 p1 = load(dirpath+'dumpvector3D_all.npy') assert round(p1[0, 0, 0] - 0.5, 7) == 0 assert round(p1[1, 1, 0] - 0.4, 7) == 0 assert round(p1[2, 1, 1] - 0.3, 7) == 0
def test_Probes_vectorfunctionspace_2D(VF2, dirpath): u0 = interpolate(Expression(('x[0]', 'x[1]'), degree=1), VF2) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), VF2) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 1] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 0] - 0.4, 7) == 0 assert round(p0[2, 1] - 0.3, 7) == 0 p0 = p.array(filename=dirpath + 'dumpvector2D') if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0, 0] - 0.5, 7) == 0 assert round(p0[1, 1, 1] - 0.4, 7) == 0 assert round(p0[2, 0, 1] - 0.3, 7) == 0 f = open(dirpath + 'dumpvector2D_all.probes', 'r') p1 = load(f) assert round(p1[0, 0, 0] - 0.5, 7) == 0 assert round(p1[1, 1, 0] - 0.4, 7) == 0 assert round(p1[2, 1, 1] - 0.3, 7) == 0
def theend_hook(q_, u_, p_, uv, mesh, ds, V, nu, Umean, D, **NS_namespace): uv() plot(uv, title='Velocity') plot(p_, title='Pressure') plot(q_['alfa'], title='alfa') R = VectorFunctionSpace(mesh, 'R', 0) c = TestFunction(R) tau = -p_*Identity(2)+nu*(grad(u_)+grad(u_).T) ff = FacetFunction("size_t", mesh, 0) Cyl.mark(ff, 1) n = FacetNormal(mesh) ds = ds[ff] forces = assemble(dot(dot(tau, n), c)*ds(1)).array()*2/Umean**2/D print "Cd = {}, CL = {}".format(*forces) from fenicstools import Probes from numpy import linspace, repeat, where, resize xx = linspace(0, L, 10000) x = resize(repeat(xx, 2), (10000, 2)) x[:, 1] = 0.2 probes = Probes(x.flatten(), V) probes(u_[0]) nmax = where(probes.array() < 0)[0][-1] print "L = ", x[nmax, 0]-0.25 print "dP = ", p_(Point(0.15, 0.2)) - p_(Point(0.25, 0.2))
def test_Probes_vectorfunctionspace_2D(VF2, dirpath): u0 = interpolate(Expression(('x[0]', 'x[1]')), VF2) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), VF2) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 1] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 0] - 0.4, 7) == 0 assert round(p0[2, 1] - 0.3, 7) == 0 p0 = p.array(filename=dirpath+'dumpvector2D') if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0, 0] - 0.5, 7) == 0 assert round(p0[1, 1, 1] - 0.4, 7) == 0 assert round(p0[2, 0, 1] - 0.3, 7) == 0 f = open(dirpath+'dumpvector2D_all.probes', 'r') p1 = load(f) assert round(p1[0, 0, 0] - 0.5, 7) == 0 assert round(p1[1, 1, 0] - 0.4, 7) == 0 assert round(p1[2, 1, 1] - 0.3, 7) == 0
def theend_hook(u_, p_, up_, mesh, ds, VQ, nu, Umean, c_, testing, **NS_namespace): if not testing: plot(u_, title='Velocity') plot(p_, title='Pressure') plot(c_, title='Scalar') R = VectorFunctionSpace(mesh, 'R', 0) c = TestFunction(R) tau = -p_*Identity(2)+nu*(grad(u_)+grad(u_).T) ff = FacetFunction("size_t", mesh, 0) Cyl.mark(ff, 1) n = FacetNormal(mesh) ds = ds(subdomain_data=ff) forces = assemble(dot(dot(tau, n), c)*ds(1)).array()*2/Umean**2/D try: print "Cd = {0:2.6e}, CL = {1:2.6e}".format(*forces) except IndexError: pass if not testing: from fenicstools import Probes from numpy import linspace, repeat, where, resize xx = linspace(0, L, 10000) x = resize(repeat(xx, 2), (10000, 2)) x[:, 1] = 0.2 probes = Probes(x.flatten(), VQ) probes(up_) nmax = where(probes.array()[:, 0] < 0)[0][-1] print "L = ", x[nmax, 0]-0.25 print "dP = ", up_(Point(0.15, 0.2))[2] - up_(Point(0.25, 0.2))[2] print "Global divergence error ", assemble(dot(u_, n)*ds()), assemble(div(u_)*div(u_)*dx())
def theend_hook(q_, u_, p_, uv, mesh, ds, V, nu, Umean, D, **NS_namespace): uv() plot(uv, title='Velocity') plot(p_, title='Pressure') plot(q_['alfa'], title='alfa') R = VectorFunctionSpace(mesh, 'R', 0) c = TestFunction(R) tau = -p_*Identity(2)+nu*(grad(u_)+grad(u_).T) ff = FacetFunction("size_t", mesh, 0) Cyl.mark(ff, 1) n = FacetNormal(mesh) ds = ds[ff] forces = assemble(dot(dot(tau, n), c)*ds(1)).array()*2/(Umean**2*D) print "Cd = {}, CL = {}".format(*forces) from fenicstools import Probes from numpy import linspace, repeat, where, resize xx = linspace(0, L, 10000) x = resize(repeat(xx, 2), (10000, 2)) x[:, 1] = 0.2 probes = Probes(x.flatten(), V) probes(u_[0]) nmax = where(probes.array() < 0)[0][-1] print "L = ", x[nmax, 0]-0.25 print "dP = ", p_(Point(0.15, 0.2)) - p_(Point(0.25, 0.2))
def test_Probes_functionspace_2D(V2): u0 = interpolate(Expression('x[0]', degree=1), V2) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), V2) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0] - 0.5, 7) == 0 assert round(p0[1] - 0.4, 7) == 0 assert round(p0[2] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0] - 0.5, 7) == 0 assert round(p0[1] - 0.4, 7) == 0 assert round(p0[2] - 0.3, 7) == 0
def test_Probes_functionspace_2D(V2): u0 = interpolate(Expression('x[0]'), V2) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), V2) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0] - 0.5, 7) == 0 assert round(p0[1] - 0.4, 7) == 0 assert round(p0[2] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0] - 0.5, 7) == 0 assert round(p0[1] - 0.4, 7) == 0 assert round(p0[2] - 0.3, 7) == 0
# BCs bc1 = DirichletBC(VV.sub(0), ((0, 0)), boundaries, 1) bc2 = DirichletBC(VV.sub(1), ((0, 0)), boundaries, 1) bcs = [bc1, bc2] # Parameters: rho_s = 1.0e3 mu_s = 0.5e6 nu_s = 0.4 E_1 = 1.4e6 lambda_ = nu_s * 2. * mu_s / (1. - 2. * nu_s) f = Constant((0, -2.)) beta = Constant(0.25) probe = Probes(coord, V) def action(wd_, t): time.append(t) probe(wd_["n"].sub(1)) # Set up different numerical schemes # TODO: Add options to chose solver and change solver parameters common = { "space": "mixedspace", "E": None, # Full implicte, not energy conservative "T": 1, # End time "dt": 0.001, # Time step "coupling": "CN", # Coupling between d and w
def main(): parser = argparse.ArgumentParser(description="Average various files") parser.add_argument("-l", "--list", nargs="+", help="List of folders", required=True) parser.add_argument("-f", "--fields", nargs="+", default=None, help="Sought fields") parser.add_argument("-t", "--time", type=float, default=0, help="Time") parser.add_argument("--show", action="store_true", help="Show") parser.add_argument("-R", "--radius", type=float, default=None, help="Radial distance") args = parser.parse_args() tss = [] for folder in args.list: ts = InterpolatedTimeSeries(folder, sought_fields=args.fields) tss.append(ts) Ntss = len(tss) all_fields_ = [] for ts in tss: all_fields_.append(set(ts.fields)) all_fields = list(set.intersection(*all_fields_)) if args.fields is None: fields = all_fields else: fields = list(set.intersection(set(args.fields), set(all_fields))) f_in = [] for ts in tss: f_in.append(ts.functions()) # Using the first timeseries to define the spaces # Could be redone to e.g. a finer, structured mesh. # ref_mesh = tss[0].mesh ref_spaces = dict([(field, f.function_space()) for field, f in f_in[0].items()]) if "psi" not in fields: exit("No psi") var_names = ["t", "s"] index_names = ["tt", "st", "ss"] index_numbers = [0, 1, 4] dim_names = ["x", "y", "z"] # Loading geometry rad_t = [] rad_s = [] g_ab = [] gab = [] for ts in tss: # Should compute these from the curvature tensor rad_t.append( df.interpolate(df.Expression("x[0]", degree=2), ts.function_space)) rad_s.append( df.interpolate(df.Expression("x[1]", degree=2), ts.function_space)) # g_loc = [ts.function(name) for name in ["gtt", "gst", "gss"]] # g_inv_loc = [ts.function(name) for name in ["g_tt", "g_st", "g_ss"]] gab_loc = dict([(idx, ts.function("g{}".format(idx))) for idx in index_names]) g_ab_loc = dict([(idx, ts.function("g_{}".format(idx))) for idx in index_names]) for idx, ij in zip(index_names, index_numbers): # for ij in range(3): # ts.set_val(g_loc[ij], ts.g[:, ij]) # ts.set_val(g_inv_loc[ij], ts.g_inv[:, ij]) ts.set_val(g_ab_loc[idx], ts.g_ab[:, ij]) # Could compute the gab locally instead of loading ts.set_val(gab_loc[idx], ts.gab[:, ij]) g_ab_loc["ts"] = g_ab_loc["st"] gab_loc["ts"] = gab_loc["st"] g_ab.append(g_ab_loc) gab.append(gab_loc) costheta = df.Function(ref_spaces["psi"], name="costheta") for its, (ts, g_ab_loc, gab_loc) in enumerate(zip(tss, g_ab, gab)): if args.time is not None: step, time = get_step_and_info(ts, args.time) g_ab_ = to_vector(g_ab_loc) gab_ = to_vector(gab_loc) ts.update(f_in[its]["psi"], "psi", step) psi = f_in[its]["psi"] psi_t = df.project(psi.dx(0), ts.function_space) psi_s = df.project(psi.dx(1), ts.function_space) gp_t = psi_t.vector().get_local() gp_s = psi_s.vector().get_local() # gtt, gst, gss = [g_ij.vector().get_local() for g_ij in g[its]] # g_tt, g_st, g_ss = [g_ij.vector().get_local() for g_ij in g_inv[its]] gtt = gab_["tt"] gst = gab_["ts"] gss = gab_["ss"] g_tt = g_ab_["tt"] g_st = g_ab_["ts"] g_ss = g_ab_["ss"] rht = rad_t[its].vector().get_local() rhs = rad_s[its].vector().get_local() rh_norm = np.sqrt(g_tt * rht**2 + g_ss * rhs**2 + 2 * g_st * rht * rhs) gp_norm = np.sqrt(gtt * gp_t**2 + gss * gp_s**2 + 2 * gst * gp_t * gp_s) costheta_loc = ts.function("costheta") # abs(cos(theta)): costheta_loc.vector()[:] = abs( (rht * gp_t + rhs * gp_s) / (rh_norm * gp_norm + 1e-8)) # cos(theta)**2: #costheta_loc.vector()[:] = ((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))**2 # sin(theta): #costheta_loc.vector()[:] = np.sin(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))) # sin(theta)**2: # costheta_loc.vector()[:] = np.sin(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8)))**2 # abs(theta): #costheta_loc.vector()[:] = abs(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))) costheta_intp = interpolate_nonmatching_mesh(costheta_loc, ref_spaces["psi"]) costheta.vector()[:] += costheta_intp.vector().get_local() / Ntss dump_xdmf(costheta) if args.show: JET = plt.get_cmap('jet') RYB = plt.get_cmap('RdYlBu') RYB_r = plt.get_cmap('RdYlBu_r') mgm = plt.get_cmap('magma') fig, ax = plt.subplots() fig.set_size_inches(4.7, 4.7) rc('text', usetex=True) rc('font', **{'family': 'serif', 'serif': ['Palatino']}) # First, dump a hires PNG version of the data: plot = df.plot(costheta, cmap=mgm) plt.axis('off') plt.savefig('anglogram_hires.png', format="png", bbox_inches='tight', pad_inches=0, dpi=500) mainfs = 10 # Fontsize titlefs = 12 # Fontsize #plt.set_cmap('jet') #cbar = fig.colorbar(plot, ticks=[0, 0.5, 1], orientation='vertical') #cbar.ax.set_yticklabels(['Radial', 'Intermediate', 'Azimuthal']) #cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.95], orientation='horizontal', fraction=0.046, pad=0.04) #cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.995], orientation='horizontal', fraction=0.046, pad=0.04) cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.9995], orientation='horizontal', fraction=0.046, pad=0.04) cbar.ax.set_xticklabels(['Radial', 'Intermediate', 'Azimuthal']) #ax.set_title('Stripe orientation -- $\\cos^2(\\theta)$', fontsize=mainfs) #ax.set_title(r'Stripe orientation -- $\cos^2(\theta)$') plt.text(0.5, 1.05, r'Stripe orientation -- $\left\vert\cos(\theta)\right\vert$', fontsize=titlefs, horizontalalignment='center', transform=ax.transAxes) #ax.set_title('Stripe orientation', fontsize=mainfs) #plt.text(0.2, 0.2, '$\\textcolor{red}{\\mathbf{p}(u,w,\\xi)}=\\textcolor{blue}{\\tilde{\\mathbf{p}}(u,w)} + \\xi \\tilde{\\mathbf{n}}(u,w)$', fontsize=mainfs) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) #plt.show() plt.savefig('anglogram.pdf', format="pdf", bbox_inches='tight', pad_inches=0) #plt.axis('on') #ax.get_xaxis().set_visible(True) #ax.get_yaxis().set_visible(True) #plt.colorbar(plot) #plt.show() if args.radius is not None and args.radius > 0: Nr, Nphi = 256, 256 r_lin = np.linspace(0., args.radius, Nr) phi_lin = np.linspace(0, 2 * np.pi, Nphi, endpoint=False) R, Phi = np.meshgrid(r_lin, phi_lin) r = R.reshape((Nr * Nphi, 1)) phi = Phi.reshape((Nr * Nphi, 1)) xy = np.hstack((r * np.cos(phi), r * np.sin(phi))) pts = xy.flatten() probes = Probes(pts, ref_spaces["psi"]) probes(costheta) ct = probes.array() CT = ct.reshape(R.shape) g_r = CT.mean(axis=0) g_phi = CT.mean(axis=1) plt.figure() plt.plot(r_lin, g_r) plt.ylabel("g(r)") plt.xlabel("r") plt.figure() plt.plot(phi_lin, g_phi) plt.xlabel("phi") plt.ylabel("g(phi)") plt.show()
def method(ts, dx=0.1, line="[0.,0.]--[1.,1.]", time=None, dt=None, skip=0, **kwargs): """ Probe along a line. """ info_cyan("Probe along a line.") try: x_a, x_b = [tuple(eval(pt)) for pt in line.split("--")] assert (len(x_a) == ts.dim) assert (len(x_b) == ts.dim) assert (all([ bool(isinstance(xd, float) or isinstance(xd, int)) for xd in list(x_a) + list(x_b) ])) except: info_on_red("Faulty line format. Use 'line=[x1,y1]--[x2,y2]'.") exit() x = np.array(line_points(x_a, x_b, dx)) info("Probes {num} points from {a} to {b}".format(num=len(x), a=x_a, b=x_b)) if rank == 0: plot_probes(ts.nodes, ts.elems, x, colorbar=False, title="Probes") f = ts.functions() probes = dict() from fenicstools import Probes for field, func in f.iteritems(): probes[field] = Probes(x.flatten(), func.function_space()) steps = get_steps(ts, dt, time) for step in steps: info("Step " + str(step) + " of " + str(len(ts))) ts.update_all(f, step) for field, probe in probes.iteritems(): probe(f[field]) probe_arr = dict() for field, probe in probes.iteritems(): probe_arr[field] = probe.array() if rank == 0: for i, step in enumerate(steps): chunks = [x] header_list = [index2letter(d) for d in range(ts.dim)] for field, chunk in probe_arr.iteritems(): if chunk.ndim == 1: header_list.append(field) chunk = chunk[:].reshape(-1, 1) elif chunk.ndim == 2: header_list.append(field) chunk = chunk[:, i].reshape(-1, 1) elif chunk.ndim > 2: header_list.extend( [field + "_" + index2letter(d) for d in range(ts.dim)]) chunk = chunk[:, :, i] chunks.append(chunk) data = np.hstack(chunks) header = "\t".join(header_list) makedirs_safe(os.path.join(ts.analysis_folder, "probes")) np.savetxt(os.path.join(ts.analysis_folder, "probes", "probes_{:06d}.dat".format(step)), data, header=header)
def solve_ht(): # error for inf temperature field if all BC are HTC bcs = { "work": { 'boundary_id': work_htc_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'HTC', 'value': htc_work, 'ambient': T_ambient } } }, "cutter": {'boundary_id': cutter_htc_boundary_id, 'values': { #'temperature': {'variable': "temperature", 'type': 'Dirichlet', 'value': T_ambient + 200} } }, 'temperature': {'variable': "temperature", 'type': 'HTC', 'value': htc_cutter, 'ambient': T_ambient } } }, "holder": {'boundary_id': holder_htc_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'HTC', 'value': htc_holder, 'ambient': T_ambient} } }, #'temperature': {'variable': "temperature", 'type': 'Dirichlet', 'value': T_ambient + 20} } }, "chip": { 'boundary_id': chip_htc_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'HTC', 'value': htc_chip, 'ambient': T_ambient } } }, #other are zero heat flux } settings = {'solver_name': 'ScalarEquationSolver', 'mesh': mesh_file, 'function_space': None, 'fe_degree': element_degree, 'periodic_boundary': pbc, 'boundary_conditions': bcs, 'body_source': None, 'initial_values': {'temperature': T_ambient}, 'material': material_work, 'solver_settings': { 'transient_settings': {'transient': False, 'starting_time': 0, 'time_step': 0.01, 'ending_time': 0.03}, 'reference_values': {'temperature': T_ambient}, 'solver_parameters': {"relative_tolerance": 1e-8, # mapping to solver.parameters of Fenics 'absolute_tolerance': 1E-9, "maximum_iterations": 500, "relaxation_parameter": 0.3, # case 6 , case 8 failed to converge "monitor_convergence": True, # print to console }, }, # solver specific settings 'scalar_name': 'temperature', "convective_velocity": None, #'radiation_settings': {'ambient_temperature': T_ambient-20, 'emissivity': 0.9} } if using_stab: # stab is not necessary if mapping boundary is used settings['advection_settings'] = {'stabilization_method': 'IP', 'alpha': IP_alpha, 'Pe': Pe/1000.0} if considering_radiation: settings['radiation_settings']= {'ambient_temperature': T_ambient, 'emissivity': emissivity} import time # dolfin has time function ts_before_preprocessing = time.time() solver = ScalarTransportSolver.ScalarTransportSolver(settings) Q = solver.function_space vector_degree = element_degree+1 V = VectorFunctionSpace(solver.mesh, 'CG', vector_degree) v_e = Expression(cppcode=velocity_code, degree=vector_degree) # degree, must match function space v_e.subdomain_id = solver.subdomains velocity = Function(V) velocity.interpolate(v_e) # does not work for MPI if has_convective_velocity: #solver.convective_velocity = Constant((1, 1, 0)) solver.convective_velocity = velocity #DG for conductivity and heat source, save to hdf5? DG0 = FunctionSpace(solver.mesh, 'DG', 0) # can not mixed higher order CG and DG? unity = Function(DG0) unity.vector()[:] = 1 #interpolate(Expression('1', element_degree), DG0) # Numerical simulations of advection-dominated scalar mixing with applications to spinal CSF flow and drug transport if not using_nonlinear_thermal_properties: k_f = get_material_function(DG0, solver.subdomains, material_k_list) solver.material['thermal_conductivity'] = k_f capacity_f = get_material_function(DG0, solver.subdomains, material_capacity_list) solver.material['capacity'] = capacity_f ################################################# shear_heat, friction_heat = get_heat_source() shear_heat_density = shear_heat / shear_heat_volume # W/m3 friction_heat_density = friction_heat / nominal_friction_heat_volume print("heating volume and intensity; ", shear_heat_volume, friction_heat_volume, shear_heat_density, friction_heat_density) if True: # test passed, non-uniform heat source can be implemented later class HeatSourceExpression(Expression): def eval_cell(self, values, x, ufc_cell): cindex = ufc_cell.index did = solver.subdomains[cindex] if did == shear_subdomain_id: values[0] = shear_heat_density elif did == friction_subdomain_id: if nonuniform_friction_heat: distance = math.sqrt(x[0]*x[0] + x[1]*x[1]) _start = (friction_heat_start + uniform_friction_heat_length) if distance <= _start: values[0] = friction_heat_density * uniform_heat_ratio else: _ratio_l = (distance -_start)/(actual_friction_heat_distance - _start) _ratio_h = uniform_heat_ratio * (1 - _ratio_l) values[0] = friction_heat_density * _ratio_h if nonuniform_friction_thickness: distance = math.sqrt(x[0]*x[0] + x[1]*x[1]) _start = friction_heat_start _ratio_l = (distance -_start)/actual_friction_heat_length _ratio_h = 1.0 / ( 1.0 - _ratio_l * ( 1.0 - friction_end_thickness/friction_heat_thickness)) values[0] = friction_heat_density * _ratio_h else: values[0] = friction_heat_density else: values[0] = 0 # FIXME: cause error of UFLException: Discontinuous type Coefficient must be restricted. v_s = HeatSourceExpression(degree = element_degree) # degree, must match function space heat_source = Function(DG0) heat_source.interpolate(v_s) # does not work for MPI solver.body_source = heat_source else: heat_source_list = [0] * subdomain_number heat_source_list[shear_subdomain_id] = shear_heat_density heat_source_list[friction_subdomain_id] = friction_heat_density heat_source = get_material_function(DG0, solver.subdomains, heat_source_list) # does not work for MPI solver.body_source = heat_source ''' solver.boundary_facets.set_all(0) for facet in facets(solver.mesh): for cell in cells(facet): #print(f.index(), c.index()) if facet.exterior() and solver.subdomains[cell.index()] < 5: solver.boundary_facets[facet.index()] = solver.subdomains[cell.index()] ''' if exporting_foam: #preset boundary value #DG vector space #v_e = Expression(cppcode=velocity_code, degree=vector_degree) # degree, must match function space? #v_e.subdomain_id = solver.subdomains #print(velocity_code) DGV = VectorFunctionSpace(solver.mesh, 'DG', 0) velocity = Function(DGV) velocity.interpolate(v_e) # does not work for MPI print(' chip volocity = ({}, {}, {})'.format(chip_sliding_vel_x, chip_sliding_vel_y, 0)) print(' work volocity = ({}, {}, {})'.format(cutting_speed, 0, 0)) sys.path.append('/media/sf_OneDrive/gitrepo/VTKToFoam') from VTKToFoam import set_internal_field, write_field foam_data_folder = '0/' #foam_data_folder = '0.origin/' #print('size of DG0 vector numpy array', velocity.vector().array().shape) # correct 1D array #print('size of DG0 scalar numpy array', heat_source.vector().array().shape) # need to regerate mesh and transform mesh even if boundary, subdomain id changed. foam_velocity_data_file = foam_data_folder + foam_data_folder + 'U' set_internal_field(foam_velocity_data_file, velocity.vector().array(), 'vector', foam_data_folder + '0.origin/U') # icoThermoFoam TEqn accepts power/capacity as source #set_internal_field(foam_data_folder + 'S', heat_source.vector().array()/metal_capacity_0, 'scalar', foam_base_folder + 'S') # if not existing, write_field() print("set heat source density in system/") sys.exit() # holder_top_boundary = AutoSubDomain(lambda x, on_boundary: \ near(x[1], holder_top_y) and on_boundary) holder_top_boundary.mark(solver.boundary_facets, holder_top_boundary_id) solver.boundary_conditions['holder_top'] = { 'boundary_id': holder_top_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'Dirichlet', 'value': T_holder_top } } } # if is_straight_chip: chip_end_boundary = AutoSubDomain(lambda x, on_boundary: \ near(x[1], chip_top_y) and on_boundary) else: chip_end_boundary = AutoSubDomain(lambda x, on_boundary: \ near(x[0], chip_center_x) and (x[1]>0) and on_boundary) chip_end_boundary.mark(solver.boundary_facets, chip_end_boundary_id) if not has_convective_velocity: solver.boundary_conditions['chipend_htc'] = { 'boundary_id': chip_end_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'HTC', 'value': htc_chip, 'ambient':T_ambient } } } if has_convective_velocity: if using_mapping_bc: # test if bc is found # those are used in post-processing, PeriodicBoundary should be done in function space creation mapping_periodic_boundary = PeriodicBoundary() mapping_periodic_boundary.mark(solver.boundary_facets, mapping_boundary_id, check_midpoint = True) # shear_interface = TurningInterface() # chip side shear_interface.mark(solver.boundary_facets, mapped_shear_boundary_id, check_midpoint = True) # if using_chip_cutter_mapping_bc: friction_interface = FrictionalInterface() # cutter side friction_interface.mark(solver.boundary_facets, mapped_friction_boundary_id, check_midpoint = True) if workpiece_type_id == 0 or workpiece_type_id == 2: # rect work shape work_bottom_boundary = AutoSubDomain(lambda x, on_boundary: near(x[1], work_bottom_y) and on_boundary) work_bottom_boundary.mark(solver.boundary_facets, work_bottom_boundary_id) # work_left_boundary_id = work_bottom_boundary_id+1 work_left_boundary = AutoSubDomain(lambda x, on_boundary: near(x[0], work_left_x) and x[1]<feed_thickness+DOLFIN_EPS and on_boundary) work_left_boundary.mark(solver.boundary_facets, work_left_boundary_id) # work_right_boundary = AutoSubDomain(lambda x, on_boundary: near(x[0], work_right_x) and x[1]<feed_thickness+DOLFIN_EPS and on_boundary) work_right_boundary.mark(solver.boundary_facets, work_bottom_boundary_id+2) #right are natural boundary, zero gradient, or it does not mater solver.boundary_conditions['work_inlet'] = { 'boundary_id': work_left_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'Dirichlet', 'value': T_work_inlet } } } #solver.boundary_conditions['work_bottom'] = { 'boundary_id': work_bottom_boundary_id, 'values': { # 'temperature': {'variable': "temperature", 'type': 'Dirichlet', 'value': T_ambient } } } elif workpiece_type_id == 1: disc_center_y = - disc_R work_clamp_boundary_id = 8 work_clamp_boundary = AutoSubDomain(lambda x, on_boundary: \ between(x[0], (-disc_R*0.05, disc_R*0.05)) \ and between(x[1], (disc_center_y-disc_R*0.1, disc_center_y+disc_R*0.1)) and on_boundary) work_clamp_boundary.mark(solver.boundary_facets, work_clamp_boundary_id) solver.boundary_conditions['work_clamp'] = { 'boundary_id': work_clamp_boundary_id, 'values': { 'temperature': {'variable': "temperature", 'type': 'Dirichlet', 'value': T_ambient } } } else: raise NotImplementedError('this work piece shape id is not supported') def update_material_property(DG0, subdomains, material_values, T_DG0, cutter_f, metal_f): # it takes very long time to complete if set individually did = np.asarray(subdomains.array(), dtype=np.int32) u = Function(DG0) u.vector()[:] = metal_f(T_DG0.vector().get_local()) # return numpy.array #print(type(u_new), u_new.size, u.vector().array().size) u.vector()[did == cutter_subdomain_id] = cutter_f(T_DG0.vector().get_local())[did == cutter_subdomain_id] #u.vector()[did == cutter_subdomain_id] = cutter_value """ for i, v in enumerate(did): if (v == cutter_subdomain_id): u.vector()[i] = cutter_value else: u.vector()[i] = metal_f(T_DG0.vector().array()[i]) """ return u ts_after_preprocessing = time.time() # my own nonliner loop, updating material property in each iteration if using_nonlinear_loop: # 3D looping is possible assert not using_MPI # setting material property may not working in parallel loop_i = 0 loop_N = 10 T_old = Function(solver.function_space) #default to zero, Yes while loop_i < loop_N: T = solver.solve() T_mean_diff = np.mean(T_old.vector()[:] - T.vector()[:]) print("=== nonlinear loop ", loop_i, " ======= ", T_mean_diff) if math.fabs(T_mean_diff) < 0.1: break T_DG0 = project(T, DG0) capacity_field = update_material_property(DG0, solver.subdomains, material_capacity_list, T_DG0, cutter_capacity_f, metal_capacity_f) solver.material['capacity'] = capacity_field k_field = update_material_property(DG0, solver.subdomains, material_k_list, T_DG0, cutter_k_f, metal_k_f) solver.material['thermal_conductivity'] = k_field #solver.solve() has considered dc/dT ignore dk/dT #to trigger this condition: if 'dc_dT' in self.material: T_old.vector()[:] = T.vector()[:] loop_i += 1 #ofile = File(result_folder + "k.pvd") # not for parallel #ofile << solver.material['thermal_conductivity'] else: T = solver.solve() ts_before_postprocessing = time.time() if using_MPI: mf = HDF5File(mpi_comm_world(), result_folder + "metal_cutting_result" +'.h5', 'w') #mf = XDMFFile(mpi_comm_world(), result_name+'.xdmf') mf.write(T, "T") mf.write(V.mesh(), "mesh") #post processing is not possible in parallel? sys.exit() else: #interpolate the higher order solution onto a finer linear space T.rename("Temperature (C)", "temperature contour") ofile = File(result_folder + "T.pvd") # not for parallel ofile << T ############################### post-processing##################### is_simulation_valid = True error_message = '' dx= Measure("dx", subdomain_data=solver.subdomains) print("================= summary =================") print("shear_heat, friction_heat by definition", shear_heat, friction_heat) volume_shear_zone = assemble(unity*dx(shear_subdomain_id)) volume_friction_zone = assemble(unity*dx(friction_subdomain_id)) print("volume_shear_zone, volume_friction_zone by integral:", volume_shear_zone, volume_friction_zone) heat_source = solver.body_source heat1 = assemble(heat_source*dx(shear_subdomain_id)) heat2 = assemble(heat_source*dx(friction_subdomain_id)) heat_chip = assemble(heat_source*dx(chip_subdomain_id)) print("shear_heat, friction_heat, heating by chip (should be zero) by integration", heat1, heat2, heat_chip) total_heat = assemble(heat_source*dx) if using_3D: heat_ratio = total_heat/(shear_heat + friction_heat) else: #total_heat = total_heat*cutter_thickness heat_ratio = total_heat*cutter_thickness/(shear_heat + friction_heat) print("total_heat, ratio of heat integral to the defined", total_heat, heat_ratio) if math.fabs(heat_ratio - 1) > validation_tol: error_message += "heat generation != heat source integration" is_simulation_valid = False print("========== heat loss from HTC =================") ds= Measure("ds", subdomain_data=solver.boundary_facets) # radiation is not added into cooling cooling_frictinal_zone = assemble(htc_work*(T-T_ambient)*ds(friction_subdomain_id)) cooling_shear_zone = assemble(htc_work*(T-T_ambient)*ds(shear_subdomain_id)) print("cooling from friction and shear zone surface", cooling_frictinal_zone, cooling_shear_zone) cooling_work = assemble(htc_work*(T-T_ambient)*ds(work_htc_boundary_id)) cooling_chip = assemble(htc_chip*(T-T_ambient)*ds(chip_htc_boundary_id)) cooling_tool = assemble(htc_cutter*(T-T_ambient)*ds(cutter_htc_boundary_id) + htc_holder*(T-T_ambient)*ds(holder_htc_boundary_id)) cooling_total_HTC = cooling_work + cooling_chip + cooling_tool + cooling_frictinal_zone + cooling_shear_zone cooling_HTC_all = assemble(htc_work*(T-T_ambient)*ds) # not all surface are HTC print("convective cooling_work, cooling_chip, cooling_tool and holder, cooling_HTC_all",\ cooling_work, cooling_chip, cooling_tool, cooling_HTC_all) print("ratio of HTC loss to generation", cooling_total_HTC/total_heat) total_heat_loss = cooling_total_HTC if considering_radiation: Stefan_constant = 5.670367e-8 # W/m-2/K-4 m_ = emissivity * Stefan_constant radiation_outflux = - m_*(T_ambient**4 - pow(T, 4)) R_work = assemble(radiation_outflux*ds(work_htc_boundary_id)) R_chip = assemble(radiation_outflux*ds(chip_htc_boundary_id)) R_tool = assemble(radiation_outflux*ds(cutter_htc_boundary_id) + radiation_outflux*ds(holder_htc_boundary_id)) R_total = R_work + R_chip + R_tool R_all_surfaces = assemble(radiation_outflux*ds) total_heat_loss += R_total print("radiative: cooling_work, cooling_chip, cooling_tool and holder", R_work, R_chip, R_tool, R_all_surfaces) if math.fabs(R_total / R_all_surfaces- 1) > 0.3: error_message += "radiation sum != radiation integration" is_simulation_valid = False print("ratio of heat generation radiative cooling", R_total/total_heat, R_all_surfaces/total_heat) else: R_total = 0 T_DG0 = interpolate(T, DG0) did = np.asarray(solver.subdomains.array(), dtype=np.int32) T_DG0.vector()[did != shear_subdomain_id] = 0.0 Tmax_shear_zone = np.max(T_DG0.vector().array()) # defined in salome_parameter.py, failed in 2D for v2017.2 try: p_probe = Point(*point_shear_surface_center_coordinates) T_probe = T(p_probe) except: T_probe = 0 Tmean_shear_zone = assemble(T*dx(shear_subdomain_id))/volume_shear_zone Tmean_friction_zone = assemble(T*dx(friction_subdomain_id))/volume_friction_zone Tmean_chip_zone = assemble(T*dx(chip_subdomain_id))/chip_volume Tmax_friction_zone = np.max(T.vector().array()) T_analytical_shear_zone, T_analytical_friction_zone = get_analytical_T() print('================ temperature prediction by FEA ==================') print('Tmean_shear_zone = ', Tmean_shear_zone) print('Tmax_shear_zone = ', Tmax_shear_zone, "T_probe = ", T_probe) print('Tmean_chip_zone = ', Tmean_chip_zone) print('Tmean_friction_zone = ', Tmean_friction_zone) print('Tmax_friction_zone = ', Tmax_friction_zone) if has_convective_velocity: #chip material flow taking away from system, how to get T_chip_end, (chip_cross_area*chip_velocity) is known #capacity = metal_density*metal_cp chip_speed = cutting_speed * (feed_thickness/chip_thickness) #QC = capacity * chip_speed* (cutter_thickness * chip_thickness) #print("outflow heat = %f * delta_T"%QC) #T_chip_end_center = T[p_chip_end_xyz] surface_normal = FacetNormal(solver.mesh) #area_shear_zone = assemble(unity*ds(shear_subdomain_id)) #area_friction_zone = assemble(unity*ds(friction_subdomain_id)) #print('area_shear_zone = ', area_shear_zone, "should ==", 2*l_AB * shear_heat_thickness + shear_heat_thickness*cutter_thickness) #print('area_friction_zone = ', area_friction_zone, "should ==", 2*actual_friction_heat_length * friction_heat_thickness) if using_nonlinear_loop: _capacity = solver.material['capacity'] _conductivity = solver.material['thermal_conductivity'] elif using_nonlinear_thermal_properties: #CG, cutter has same material with metal, no difference #T_DG0 = interpolate(T, DG0) #_capacity = update_material_property(DG0, solver.subdomains, material_capacity_list, T_DG0, material_cutter['capacity'], metal_capacity_f) #_conductivity = update_material_property(DG0, solver.subdomains, material_k_list, T_DG0, material_cutter['capacity'], metal_k_f) _capacity = metal_capacity_f(T) _conductivity = metal_k_f(T) else: _capacity = Constant(metal_density*metal_cp_0) _conductivity = metal_k_0 _density = metal_density system_heat_capacity = assemble((T-Constant(T_reference)) * _capacity*_density*dx) print("characteristic time = ", system_heat_capacity/total_heat) # too big not quite usful if using_mapping_bc: #validation print('============ mapping bc validation ================') if using_3D: _area_theory = l_AB*cutter_thickness else: _area_theory = l_AB area_mapping = assemble(unity*ds(mapping_boundary_id)) print('area mapping bounadry and theroetical (should be equal): ', area_mapping, _area_theory) area_mapped_shear = assemble(unity*ds(mapped_shear_boundary_id)) if using_workpiece_extra_extusion: if math.fabs(area_mapping / (_area_theory) - 1) > validation_tol: error_message += "\n mapping interface area is not equal\n" is_simulation_valid = False M_mapping = assemble(dot(surface_normal, velocity)*ds(mapping_boundary_id)) # not equal, why? print('mass flux from mapping bounadries vs in theory (should be equal): ', M_mapping, cutting_speed*cutter_thickness*feed_thickness) Q_mapping_bottom = assemble(dot(surface_normal, velocity) * (T-T_reference)*_capacity*ds(mapping_boundary_id)) Q_mapping_top = assemble(dot(surface_normal, velocity) * (T-T_reference)*_capacity*ds(mapped_shear_boundary_id)) print('heat flux from mapping bounadries (should be equal): ', Q_mapping_top, Q_mapping_bottom) if using_workpiece_extra_extusion: if math.fabs(math.fabs(Q_mapping_top / Q_mapping_bottom) - 1) > validation_tol: error_message += "\n heat flux on mapping interfaces area is not equal\n" is_simulation_valid = False Q_mapping_work = assemble(_conductivity*dot(grad(T), surface_normal) * ds(mapping_boundary_id)) * -1 Q_mapping_chip = assemble(_conductivity*dot(grad(T), surface_normal) * ds(mapped_shear_boundary_id)) * -1 print("conductive heat transfer, Q_mapping_work, Q_mapping_chip", Q_mapping_work, Q_mapping_chip) if using_chip_cutter_mapping_bc: area_mapped_friction = assemble(unity*ds(mapped_friction_boundary_id)) print('area for a chip-cutter fricitonal interface and theroetical value (should be equal): ', \ area_mapped_friction, actual_friction_heat_length*cutter_thickness) # 2D has diff area print('total area for mapping (should be equal to), and sum of cutter and work', \ area_mapping, area_mapped_friction+area_mapped_shear) print('============ heat with mass flow ================') # heat loss due to mass flow, should be zero _tmp = dot(surface_normal, velocity) * (T-Constant(T_reference)) * _capacity Q_friction = assemble(_tmp*ds(friction_subdomain_id)) print("heat flow with mass out of system from friction zone is:", Q_friction) Q_shearing = assemble(_tmp*ds(shear_subdomain_id)) print("heat flow with mass out of system from sheairing zone is:", Q_shearing) Q_chip = assemble(_tmp*ds(chip_htc_boundary_id)) print("heat flow with mass out of system from chip htc boundary is:", Q_chip) Q_work = assemble(_tmp*ds(work_htc_boundary_id)) print("heat flow with mass out of system from work htc boundary (should be zero)is:", Q_work) Q_cutter = assemble(_tmp*ds(cutter_htc_boundary_id)) print("heat flow with mass out of system from cutter htc is:", Q_cutter) Q_holder = assemble(_tmp*ds(holder_htc_boundary_id)) print("heat flow with mass out of system from holder htc is:", Q_holder) Q_chipend = assemble(_tmp*ds(chip_end_boundary_id)) print("heat flow with mass from chipend", Q_chipend) if has_friction_transition_zone: # no using mapping bc for friction contact Q_friction_transition_subdomain = assemble(_tmp*ds(friction_transition_subdomain_id)) print("heat flow with mass from friction_transition_subdomain", Q_friction_transition_subdomain) Q_ds0 = assemble(_tmp*ds(0)) print("heat flow with mass from ds(0), should be zero", Q_ds0) total_heat_loss += Q_chipend # Q_material_out_sum, excluding the workpiece outlet """ print('============ mass flow ================') M_shearing = assemble(dot(surface_normal, velocity)*ds(shear_subdomain_id)) print("mass flow out of system from shearing zone boundary is:", M_shearing) M_friction = assemble(dot(surface_normal, velocity)*ds(friction_subdomain_id)) print("mass flow out of system from friction boundary is:", M_friction) M_work = assemble(dot(surface_normal, velocity)*ds(work_htc_boundary_id)) print("mass flow out of system from work is:", M_work) M_chip = assemble(dot(surface_normal, velocity)*ds(chip_htc_boundary_id)) print("mass flow out of system from chip HTC boundary is:", M_chip) M_chipend = assemble(dot(surface_normal, velocity)*ds(chip_end_boundary_id)) print("mass flow from chip end in theory VS integral at chipend", chip_speed * (cutter_thickness * chip_thickness), M_chipend) """ Q_material_out = assemble(_tmp*ds) if workpiece_type_id == 0: #rectangle #Q_bottom = cutting_speed * capacity *ds(work_bottom_boundary_id) Q_inflow = assemble( (T-Constant(T_reference))* cutting_speed * _capacity * ds(work_bottom_boundary_id + 1)) #* cutter_thickness * (chip_start_y - work_bottom_y) Q_outflow = assemble( (T-Constant(T_reference))* cutting_speed * _capacity * ds(work_bottom_boundary_id + 2)) print('inflow from left boundary and outflow from right bounadry is', Q_inflow, Q_outflow) Q_bottom = assemble(_conductivity*dot(grad(T), surface_normal)*ds(work_bottom_boundary_id)) * -1 #flow out if using_workpiece_extra_extusion: Q_flowing_out_work = (Q_material_out - Q_chipend) + Q_bottom else: Q_flowing_out_work = (Q_outflow - Q_inflow) + Q_bottom print('heat flow out from work oulet and bottom is:', Q_flowing_out_work) total_heat_loss += Q_flowing_out_work else: # disc clamping Q_clamp = assemble(_conductivity*dot(grad(T), surface_normal)*ds(work_clamp_boundary_id)) * -1 #flow out print('heat flux from clamp bounadry is', Q_clamp) Q_flowing_out_work = Q_clamp + cooling_work total_heat_loss += Q_flowing_out_work Q_material_out_sum = Q_chip + Q_work + Q_cutter + Q_holder + Q_chipend + Q_outflow + Q_inflow print("heat flow with mass out of system from all boundary byintegral (ds) and sum:", Q_material_out, Q_material_out_sum) if math.fabs(Q_material_out_sum/Q_material_out - 1.0) > validation_tol*0.2: error_message += "\n heat flow with mass out of system from all boundary byintegral (ds) and sum is not equal\n" is_simulation_valid = False print('=============== conduction heat loss ===========') Q_conduction_all = assemble(_conductivity*dot(grad(T), surface_normal) * ds) * -1 # surface_normal pointing out Qk_chipend = assemble(_conductivity*dot(grad(T), surface_normal)*ds(chip_end_boundary_id)) * -1# flow out print('conductive heat flux from bottom and chipend bounadries', Q_bottom, Qk_chipend) #should be set zero-flux Qk_holder_top = assemble(_conductivity*dot(grad(T), surface_normal) * ds(holder_top_boundary_id)) * -1 #flow out Q_conduction_work = assemble(_conductivity*dot(grad(T), surface_normal) * ds(work_subdomain_id)) * -1 Q_conduction_chip = assemble(_conductivity*dot(grad(T), surface_normal) * ds(chip_subdomain_id)) * -1 Q_conduction_tool = assemble(_conductivity*dot(grad(T), surface_normal) * ds(holder_subdomain_id)) * -1 +\ assemble(_conductivity*dot(grad(T), surface_normal) * ds(cutter_subdomain_id)) * -1 Qk_bottom = assemble(_conductivity*dot(grad(T), surface_normal) * ds(work_bottom_boundary_id)) * -1 Qk_inlet= assemble(_conductivity*dot(grad(T), surface_normal) * ds(work_bottom_boundary_id + 1)) * -1 Qk_outlet= assemble(_conductivity*dot(grad(T), surface_normal) * ds(work_bottom_boundary_id + 2)) * -1 print('conductive heat at holder top, Qk_bottom, Qk_inlet, Qk_outlet, conduction all is',\ Qk_holder_top, Qk_bottom, Qk_inlet, Qk_outlet, Q_conduction_all) print('Q_conduction_tool, Q_conduction_work, Q_conduction_chip',\ Q_conduction_tool, Q_conduction_work, Q_conduction_chip) total_heat_loss += Qk_holder_top print('=============== heat loss ratios ===========') Q_baseline = total_heat_loss print("convection, radiation, Q_flowing_out_work, Q_bottom, Q_chipend, Q_holder_top") _ratios = np.array([cooling_total_HTC, R_total, Q_flowing_out_work, Q_bottom, Q_chipend, Qk_holder_top])/Q_baseline print(_ratios) Q_total_passing_friction_interface = (Qk_holder_top + cooling_tool) partition_coeff_shear = 1.0 - Q_flowing_out_work/ shear_heat partition_coeff_friction = 1.0 - Q_total_passing_friction_interface/ friction_heat print("partition_coeff_shear, partition_coeff_friction = ", partition_coeff_shear, partition_coeff_friction) print("ratio of total heat loss {}, heat generation {}, ratio {}"\ .format(total_heat_loss, total_heat, total_heat_loss/total_heat)) if math.fabs(total_heat_loss/total_heat - 1.0) > validation_tol: error_message += "\n heat generaton and heat loss are not equal\n" is_simulation_valid = False ts_after_post_processing = time.time() print('=============== time consumption ===========') print('preprocessing time', ts_after_preprocessing - ts_before_preprocessing) print('assembling and LA solving time', ts_before_postprocessing - ts_after_preprocessing) if using_debug: #plot(solver.boundary_facets) bfile = File(result_folder + "boundary.pvd") # not working for parallel bfile << solver.boundary_facets if using_debug: ofile = File(result_folder + "HeatSource.pvd") # not for parallel ofile << solver.body_source #it is possible to save DG0 data if has_convective_velocity and using_debug: ofile = File(result_folder + "U.pvd") # not for parallel, using hdf5 for parallel ofile << velocity if not is_batch_mode: if using_VTK: plot(solver.boundary_facets, title = "boundary id") plot(solver.subdomains, title = "subdomain id") plot(heat_source, title = "heat source density (W/m3)") #plot(solver.material['specific_heat_capacity'], title = "specific_heat_capacity") # can not plot DG plot(velocity, title = "pseudo convective velocity") interactive() solver.plot() # plt.legend() does not work: warnings.warn("No labelled objects found. " else: import matplotlib.pyplot as plt solver.plot() plt.show() #`paraview --data=T.pvd` if is_simulation_valid == False: print("======== the simulation is INVALID ! ==================") print(error_message) #if not using_workpiece_extra_extusion: # sys.exit() else: print("======== the simulation is completed sucessfully ==================") thermal_number = metal_density * metal_cp_f(T_analytical_shear_zone) * cutting_speed * feed_thickness / metal_k_f(T_analytical_shear_zone) partition_coeff_eq = get_heat_partition(thermal_number) #also save thermal_number from datetime import datetime time_stamp = datetime.utcnow().isoformat() parameters = [time_stamp, case_id, workpiece_type_id, feed_thickness, chip_thickness, cutter_angle_v, shear_angle, cutting_speed, F_cutting, F_thrush, shear_heat_thickness, friction_heat_thickness, tool_chip_interface_length, T_ambient, T_analytical_shear_zone, T_analytical_friction_zone, Tmean_shear_zone, Tmax_shear_zone, Tmean_friction_zone, Tmax_friction_zone, thermal_number, partition_coeff_eq, partition_coeff_shear, partition_coeff_friction, is_simulation_valid] output = ",".join([str(v) for v in parameters]) with open(result_filename, 'a') as wf: wf.write(output) wf.write('\n') if extracting_data: #sys.path.append('/opt/fenicstools/') # this package must be installed from fenicstools import Probes dist = np.linspace(0, tool_chip_interface_length, 20) probing_pts = np.array([(math.sin(cutter_angle_v*pi/180)*l, math.cos(cutter_angle_v*pi/180)*l, 0) for l in dist]) probes = Probes(probing_pts.flatten(), solver.function_space) probes(T) # evaluate f at all probing points extracted_datafile = result_folder + datafile_root + '__' + param_name + '__' + str(param_value) + '.csv' np.savetxt(probes.array(), extracted_datafile) print(probes.array())
# Make probe points probe_list = [-30, -25] + range(-20, 0, 2) + range(46) + range(50, 100, 2) probe_points = [] for j in range(2, -3, -1): probe_points += [[r_1 * j, 0, r_1 * 2 * i] for i in probe_list] probe_points = array(probe_points) probe_points.dump(path.join(newfolder, "Stats", "Probes", "points")) eval_dict["senterline_u"] = StatisticsProbes(eval_senter.flatten(), Pv, True) eval_dict["senterline_p"] = StatisticsProbes(eval_senter.flatten(), Pv, True) eval_dict["initial_u"] = StatisticsProbes(eval_senter.flatten(), Pv, True) eval_dict["wall_p"] = StatisticsProbes(eval_wall.flatten(), Pv, True) eval_dict["senterline_u_probes"] = Probes(probe_points.flatten(), Vv) eval_dict["senterline_p_probes"] = Probes(probe_points.flatten(), Pv) # Finding the mean velocity u_mean = {"u": Function(Vv), "num": 0} if restart_folder is None: # Print header if MPI.rank(mpi_comm_world()) == 0: print_header(dt, mesh.hmax(), mesh.hmin(), case, start, stop, inlet_string, mesh.num_cells(), newfolder, mesh_path) else: # Restart stats files = listdir(path.join(newfolder, "Stats")) files = [
def main(): parser = argparse.ArgumentParser(description="Average various files") parser.add_argument("-l", "--list", nargs="+", help="List of folders", required=True) parser.add_argument("-f", "--fields", nargs="+", default=None, help="Sought fields") parser.add_argument("-t", "--time", type=float, default=0, help="Time") parser.add_argument("--show", action="store_true", help="Show") parser.add_argument("-R", "--radius", type=float, default=None, help="Radial distance") args = parser.parse_args() tss = [] for folder in args.list: ts = InterpolatedTimeSeries(folder, sought_fields=args.fields) tss.append(ts) Ntss = len(tss) all_fields_ = [] for ts in tss: all_fields_.append(set(ts.fields)) all_fields = list(set.intersection(*all_fields_)) if args.fields is None: fields = all_fields else: fields = list(set.intersection(set(args.fields), set(all_fields))) f_in = [] for ts in tss: f_in.append(ts.functions()) # Using the first timeseries to define the spaces # Could be redone to e.g. a finer, structured mesh. # ref_mesh = tss[0].mesh ref_spaces = dict([(field, f.function_space()) for field, f in f_in[0].items()]) if "psi" not in fields: exit("No psi") # Loading geometry rad_t = [] rad_s = [] g = [] g_inv = [] for ts in tss: # Should compute these from the curvature tensor rad_t.append( df.interpolate(df.Expression("x[0]", degree=2), ts.function_space)) rad_s.append( df.interpolate(df.Expression("x[1]", degree=2), ts.function_space)) g_loc = [ts.function(name) for name in ["gtt", "gst", "gss"]] g_inv_loc = [ts.function(name) for name in ["g_tt", "g_st", "g_ss"]] for ij in range(3): ts.set_val(g_loc[ij], ts.g[:, ij]) # Could compute the following locally instead of loading ts.set_val(g_inv_loc[ij], ts.g_inv[:, ij]) g.append(g_loc) g_inv.append(g_inv_loc) costheta = df.Function(ref_spaces["psi"], name="costheta") for its, ts in enumerate(tss): if args.time is not None: step, time = get_step_and_info(ts, args.time) ts.update(f_in[its]["psi"], "psi", step) psi = f_in[its]["psi"] psi_t = df.project(psi.dx(0), ts.function_space) psi_s = df.project(psi.dx(1), ts.function_space) gp_t = psi_t.vector().get_local() gp_s = psi_s.vector().get_local() gtt, gst, gss = [g_ij.vector().get_local() for g_ij in g[its]] g_tt, g_st, g_ss = [g_ij.vector().get_local() for g_ij in g_inv[its]] rht = rad_t[its].vector().get_local() rhs = rad_s[its].vector().get_local() rh_norm = np.sqrt(g_tt * rht**2 + g_ss * rhs**2 + 2 * g_st * rht * rhs) gp_norm = np.sqrt(gtt * gp_t**2 + gss * gp_s**2 + 2 * gst * gp_t * gp_s) costheta_loc = df.Function(ts.function_space) costheta_loc.vector()[:] = abs( (rht * gp_t + rhs * gp_s) / (rh_norm * gp_norm + 1e-8)) costheta_intp = interpolate_nonmatching_mesh(costheta_loc, ref_spaces["psi"]) costheta.vector()[:] += costheta_intp.vector().get_local() / Ntss dump_xdmf(costheta) if args.show: fig = df.plot(costheta) plt.colorbar(fig) plt.show() if args.radius is not None and args.radius > 0: Nr, Nphi = 256, 256 r_lin = np.linspace(0., args.radius, Nr) phi_lin = np.linspace(0, 2 * np.pi, Nphi, endpoint=False) R, Phi = np.meshgrid(r_lin, phi_lin) r = R.reshape((Nr * Nphi, 1)) phi = Phi.reshape((Nr * Nphi, 1)) xy = np.hstack((r * np.cos(phi), r * np.sin(phi))) pts = xy.flatten() probes = Probes(pts, ref_spaces["psi"]) probes(costheta) ct = probes.array() CT = ct.reshape(R.shape) g_r = CT.mean(axis=0) g_phi = CT.mean(axis=1) plt.figure() plt.plot(r_lin, g_r) plt.ylabel("g(r)") plt.xlabel("r") plt.figure() plt.plot(phi_lin, g_phi) plt.xlabel("phi") plt.ylabel("g(phi)") plt.show()