e0 = np.deg2rad(10) # Solar elevation angle F0 = 1365 # Solar constant albedo = 0.3 emiss = 0.95 dir_sun = np.array([0, -np.cos(e0), np.sin(e0)]) # Direction of sun # Compute the direct irradiance and find the elements which are in shadow. tic() E = shape_model.get_direct_irradiance(F0, dir_sun) t_E = toc() I_shadow = E == 0 print('Number of elements in E =', E.shape[0]) # Make plot of direct irradiance fig, ax = tripcolor_vector(V, F, E, cmap=cmap['gray']) fig.savefig('E.png') plt.close(fig) print('- wrote E.png') tic() B, niter_B = solve_radiosity(FF, E, rho=albedo) t_B = toc() print('- computed radiosity [%1.2f s]' % (t_B, )) fig, ax = tripcolor_vector(V, F, B, cmap=cc.cm.gray) fig.savefig('B.png') plt.close(fig) print('- wrote B.png') tic()
print('- Number of vertices', V.shape[0], 'Number of facets', F.shape[0]) # Define constants used in the simulation: e0 = np.deg2rad(10) # Solar elevation angle F0 = 1365 # Solar constant albedo = 0.3 emiss = 0.95 dir_sun = np.array([0, -np.cos(e0), np.sin(e0)]) # Direction of sun # Compute the direct irradiance and find the elements which are in shadow. E = shape_model.get_direct_irradiance(F0, dir_sun) print('Number of elements in E =', E.shape[0]) # Make plot of direct irradiance fig, ax = tripcolor_vector(V, F, E, cmap='gray') fig.savefig('E.png') plt.close(fig) print('- wrote E.png') # calculate analytical solution for bowl-shaped crater Texact = exact_solution_ingersoll(F0, e0, albedo, emiss, 5., P, N, E, dir_sun) fig, ax = tripcolor_vector(V, F, Texact, cmap='inferno') fig.savefig('Texact.png') plt.close(fig) print('- wrote Texact.png') # set provisional values Qabs = (1 - albedo) * E
def illuminate_form_factor(FF_path = 'lsp_compressed_form_factors.bin', compressed=True, plot_fluxes=False, use_svd=False): """ Compute Sun position, illuminate FF and compute irradiance and temperature Args: FF_path: input form factor matrix compressed: bool, is the input FF compressed Returns: dict """ # clktol = '10:000' spice.kclear() spice.furnsh('simple.furnsh') # Define time window et0 = spice.str2et('2011 MAR 01 00:00:00.00') et1 = spice.str2et('2011 APR 01 00:00:00.00') et = np.linspace(et0, et1, 10, endpoint=False) stepet = et[1]-et[0] # Sun positions over time period possun = spice.spkpos('SUN', et, 'MOON_ME', 'LT+S', 'MOON')[0] lonsun = np.arctan2(possun[:, 1], possun[:, 0]) lonsun = np.mod(lonsun, 2*np.pi) radsun = np.sqrt(np.sum(possun[:, :2]**2, axis=1)) latsun = np.arctan2(possun[:, 2], radsun) sun_dirs = np.array([ np.cos(lonsun)*np.cos(latsun), np.sin(lonsun)*np.cos(latsun), np.sin(latsun) ]).T # Load compressed form factor matrix, including shape model, from disk if use_svd: V = np.load('lsp_V.npy') F = np.load('lsp_F.npy') N = np.load('lsp_N.npy') shape_model = TrimeshShapeModel(V, F, N) elif compressed: logging.warning("Retrieving compressed FF block and shape_model...") FF = cff.CompressedFormFactorMatrix.from_file(FF_path) shape_model = FF.shape_model V = FF.shape_model.V F = FF.shape_model.F else: logging.warning("Retrieving full FF block and shape_model...") FF = ff.FormFactorMatrix.from_file(FF_path) V = np.load('lsp_V.npy') F = np.load('lsp_F.npy') N = np.load('lsp_N.npy') shape_model = TrimeshShapeModel(V, F, N) # illuminate FF E_arr = [] for i, sun_dir in enumerate(sun_dirs[:]): E_arr.append(shape_model.get_direct_irradiance(F0, sun_dir)) E = np.vstack(E_arr).T Qrefl = [] QIR = [] T = [] if steady_state: # Compute steady state temperature T_arr = compute_steady_state_temp(FF, E, albedo, emiss) T = np.vstack(T_arr).T elif False: # spin-up model until equilibrium is reached # generate 1D grid nz = 60 zfac = 1.05 zmax = 2.5 z = setgrid(nz=nz, zfac=zfac, zmax=zmax) # compute provisional Tsurf and Q from direct illumination only Qabs0 = (1 - albedo) * E[:, 0] + Fgeoth Tsurf0 = (Qabs0 / (sigSB * emiss)) ** 0.25 # set up model (with Qprev = Qabs0) model = PccThermalModel1D(nfaces=E.shape[0], z=z, T0=210, ti=120., rhoc=960000., # we have rho, but how do we get c? emissivity=emiss, Fgeotherm=Fgeoth, Qprev=Qabs0.astype(np.double), bcond='Q') # loop over time-steps/sun angles T = [model.T[:,0]] for i in range(len(sun_dirs) - 1): # get Q(np1) as in Eq. 17-19 if i == 0: Qrefl_np1, QIR_np1 = update_incoming_radiances(FF, E[:, i + 1], albedo, emiss, Qrefl=0, QIR=0, Tsurf=Tsurf0) else: Qrefl_np1, QIR_np1 = update_incoming_radiances(FF, E[:, i + 1], albedo, emiss, Qrefl=Qrefl_np1, QIR=QIR_np1, Tsurf=model.T[:, 0]) # compute Qabs, eq 19 radiosity paper Qnp1 = (1 - albedo) * (E[:, i + 1] + Qrefl_np1) + emiss * QIR_np1 # extrapolate model at t_{i+1}, get model.T(i+1) model.step(stepet, Qnp1) # add check for steady-state (model.T(i) - model.T(i-1) < eps) to break loop T.append(model.T[:,0]) # adapt shapes for plotting T = np.vstack(T).T else: # loop over time-steps/sun angles for i in range(len(sun_dirs) - 1): Qabs0 = (1 - albedo) * E[:, i] + Fgeoth Tsurf0 = (Qabs0 / (sigSB * emiss)) ** 0.25 if not use_svd: # get Q(np1) as in Eq. 17-19 if i == 0: Qrefl_np1, QIR_np1 = update_incoming_radiances(FF, E[:, i + 1], albedo, emiss, Qrefl=0., QIR=0., Tsurf=Tsurf0) else: Qrefl_np1, QIR_np1 = update_incoming_radiances(FF, E[:, i + 1], albedo, emiss, Qrefl=Qrefl_np1, QIR=0., Tsurf=Tsurf0) else: # read outputs of xSVDcomputation U = np.loadtxt('svd_U.dat'); sigma = np.loadtxt('svd_sigma.dat') Vt = np.loadtxt('svd_V.dat') if i == 0: Qrefl_np1, QIR = update_incoming_radiances_wsvd(E[:, i + 1], albedo, emiss, 0, 0, Tsurf0, Vt, sigma, U) else: Qrefl_np1, QIR = update_incoming_radiances_wsvd(E[:, i + 1], albedo, emiss, Qrefl_np1, 0, Tsurf0, Vt, sigma, U) # save Qrefl Qrefl.append(Qrefl_np1) T.append(Tsurf0) # adapt shapes for plotting Qrefl = np.vstack(Qrefl).T T = np.vstack(T).T Path(f"./frames").mkdir(parents=True, exist_ok=True) if plot_fluxes: for i, sun_dir in enumerate(sun_dirs[:]): print('frame = %d' % i) fig, ax = tripcolor_vector(V, F, E[:,i], cmap=cc.cm.gray) fig.savefig(f"./frames/lsp_E1_%03d.png" % i) plt.close(fig) fig, ax = tripcolor_vector(V, F, T[:,i], cmap=cc.cm.fire) fig.savefig(f"./frames/lsp_T1_%03d.png" % i) plt.close(fig) I_shadow = E[:,i] == 0 fig, ax = tripcolor_vector(V, F, T[:,i], I=I_shadow, cmap=cc.cm.rainbow, vmax=100) fig.savefig(f"./frames/lsp_T1_shadow_%03d.png" % i) plt.close(fig) # starting E from second element, to have same number of elements on all arrays return {"V":V,"F":F,"E":E[:,1:],'Qrefl':Qrefl,"QIR":QIR,"T":T}
if args.blocks and args.tol: tic() fig, ax = plot_blocks(FF._root) fig.savefig(os.path.join(args.outdir, 'blocks.png')) plt.close(fig) print('- wrote blocks.png [%1.2f s]' % (toc(),)) dir_sun = np.array([np.cos(e0), 0, np.sin(e0)]) tic() E = shape_model.get_direct_irradiance(args.F0, dir_sun, eps=1e-6) t_E = toc() print('- computed direct irradiance [%1.2f s]' % (t_E,)) fig, ax = tripcolor_vector(V, F, E, cmap=cc.cm.gray) fig.savefig(os.path.join(args.outdir, 'E.png')) plt.close(fig) print('- wrote E.png to disk') tic() B, niter_B = solve_radiosity(FF, E, rho=args.rho) t_B = toc() print('- computed radiosity [%1.2f s]' % (t_B,)) fig, ax = tripcolor_vector(V, F, B, cmap=cc.cm.gray) fig.savefig(os.path.join(args.outdir, 'B.png')) plt.close(fig) print('- wrote B.png') tic()
V = d['full']['V'] F = d['full']['F'] if test_svd: residuals = np.abs(d['full']['Qrefl'] - d['svd']['Qrefl']) # # else: residuals = np.abs(d['full']['Qrefl'] - d['compressed']['Qrefl']) # # print(len(residuals)) step2_res = residuals[:, 8] print(np.where(step2_res > 1.e14)) # exit() # plot residuals for i in range(residuals.shape[1]): # print('frame = %d' % i) fig, ax = tripcolor_vector(V, F, residuals[:, i], vmax=1.e14) fig.savefig(f"./frames/lsp_dfc32_%03d.png" % i) plt.close(fig) fig, ax = tripcolor_vector(V, F, d['full']['Qrefl'][:, i], vmax=1.e16) fig.savefig(f"./frames/lsp_fd32_%03d.png" % i) plt.close(fig) fig, ax = tripcolor_vector(V, F, d['compressed']['Qrefl'][:, i], vmax=1.e16) fig.savefig(f"./frames/lsp_cd32_%03d.png" % i) plt.close(fig) if test_svd:
I_shadow = E == 0 # Compute the steady state temperature. This function is at the # top of this file. T = compute_steady_state_temp(FF, E, rho, emiss) print('computed T') # Finally, we make some plots showing what we just did, and write # them to disk: fig, ax = plot_blocks(FF._root) fig.savefig('haworth_blocks.png') plt.close(fig) print('wrote haworth_blocks.png to disk') fig, ax = tripcolor_vector(V, F, E, cmap=cmap['gray']) fig.savefig('haworth_E.png') plt.close(fig) print('wrote haworth_E.png to disk') fig, ax = tripcolor_vector(V, F, T, vmin=0, vmax=400, cmap=cmap['fire']) fig.savefig('haworth_T.png') plt.close(fig) print('wrote haworth_T.png to disk') fig, ax = tripcolor_vector(V, F, T, I=I_shadow, cmap=cmap['jet']) fig.savefig('haworth_T_shadow.png') plt.close(fig) print('wrote haworth_T_shadow.png to disk') # Use pyvista to make a nice 3D plot of the temperature.
V = np.row_stack([V.T, np.array([z(*v)[0] for v in V])]).T num_faces = F.shape[0] print('created mesh with %d triangles' % num_faces) # Let's use another Python library (meshio) to save the triangle # mesh as an OBJ file (optional). points = V cells = [('triangle', F)] mesh = meshio.Mesh(points, cells) mesh_path = 'mesh%d.obj' % num_faces mesh.write(mesh_path) print('wrote %s to disk' % mesh_path) # Make plot of topography fig, ax = tripcolor_vector(V, F, V[:, 2], cmap=cmap['jet']) fig.savefig('topo2.png') plt.close(fig) print('wrote topo2.png') # Since Embree runs in single precision, there's no reason to use # double precision here. V = V.astype(np.float32) # Create a triangle mesh shape model using the vertices (V) and # face indices (F). shape_model = TrimeshShapeModel(V, F) # Build the compressed form factor matrix. All of the code related # to this can be found in the "form_factors.py" file in this # directory.