""" import os, sys lib_path = os.path.abspath('..') sys.path.append(lib_path) from Classes import Simulation from Interpreter import Interpreter from Solver import Solver from write import write_vtk, write_solver_input import matplotlib.pyplot as plt from matplotlib import rc filename = 'unit_cell_1-02_two_reg' write_solver_input(filename +'.msh',dimension = 2, bc_type = 'Bloch', \ parameter = [], eq = 'EM', sol_type = 'Stationary',analysis_param \ = ['y', 'y', 15, 15, 21, 21, 5], bc_filename = filename +'_guide.bc') simu = Simulation() simu.read_solver_input(filename +'.msh') simu.domain.read_mesh_file(filename +'.msh',simu) inter = Interpreter(vectorial = True) eq = inter.build_EM_bloch_eq(simu) my_solver = Solver() k_coords, energy = my_solver.solve_bloch_Brillouin(simu, eq) fig = plt.figure() ax = fig.add_subplot(111) plt.title("Dispersion relations for Square lattice") k_div = k_coords.shape[0]/3
Created on Tue Mar 19 11:31:57 2013 @author: santiago """ import os, sys lib_path = os.path.abspath('../../') sys.path.append(lib_path) from Classes import Simulation from Interpreter import Interpreter from Solver import Solver from write import write_vtk, write_solver_input from numpy import zeros filename = 'whole_cylinder' write_solver_input(filename +'.msh',dimension = 2, bc_type = 'Dir', \ parameter = [], eq = 'EM', sol_type = 'Stationary',analysis_param \ = ['y', 'y', 4, 4, 20, 20, 2], bc_filename = filename+'.bc') simu = Simulation() simu.read_solver_input(filename +'.msh') simu.domain.read_mesh_file(filename +'.msh', True) simu.domain.read_bc_file(simu.bc_filename) reg_filename = simu.bc_filename.split('.bc')[0] simu.domain.read_regions_file(reg_filename) inter = Interpreter() eq = inter.build_static_EM_eq(simu) g = eq['sol_vec'] my_solver = Solver()
lib_path = os.path.abspath("../../../") sys.path.append(lib_path) from Classes import Simulation from Interpreter import Interpreter from Solver import Solver from write import write_vtk, write_solver_input from numpy import pi, sqrt from numpy import zeros filename = "finite_lattice_all_inclusions" write_solver_input( filename + ".msh", dimension=2, bc_type="Dir", parameter=[], eq="EM", sol_type="Stationary", analysis_param=["y", "y", 15, 15, 20, 20, 2], bc_filename=filename + ".bc", ) simu = Simulation() simu.read_solver_input(filename + ".msh") simu.domain.read_mesh_file(filename + ".msh", True) simu.domain.read_bc_file(simu.bc_filename) reg_filename = simu.bc_filename.split(".bc")[0] simu.domain.read_regions_file(reg_filename) inter = Interpreter() eq = inter.build_harmonic_EM_eq(simu)
from PrePro import Mesh1D,Potential1D,meshPlot,Mesh2D from write import write_msh, write_vtk, write_solver_input from solver import schroedinger from math import pi import numpy as np from PostPro import plot_1d from time import time t0 = time() nodes, elements = Mesh1D('simple',0,2*pi) write_msh('lineSimple.msh', nodes, elements) pot = Potential1D('well', nodes, V0=2) write_solver_input('lineSimple.msh', parameter = pot, bc_type = 'Bloch',\ analysis_param = ['y', 'y', 4, 4, 50, 50, 1]) v, d = schroedinger('lineSimple.msh') tf = time() z = np.zeros((nodes.size, 3)) z[:, 0] = nodes nodes = z #write_vtk('test.vtk', 'thi shit', '', nodes, elements, \ # ['SCALARS', ['Pot', 'Psi'], [pot, d]]) plot_1d('', nodes = nodes,elements = elements, parameter = pot, bc_type = 'Dir', \ sol = d) print 'time elapsed: \n', tf-t0, 'seconds' ##Nodes=Nodes[:,0] ##WriteMSH('lineSimple.msh',Nodes,Elems) ##Nodes,Elems=ReadVTK('test.vtk')
# -*- coding: utf-8 -*- """ Created on Sat Apr 6 20:06:58 2013 @author: santiago """ from Classes import Simulation from Interpreter import Interpreter from Solver import Solver from write import write_vtk, write_solver_input write_solver_input('whole_cylinder.msh',dimension = 2, bc_type = 'Dir', \ parameter = [], eq = 'Harm_Elec', sol_type = 'Stationary',analysis_param \ = ['y', 'y', 4, 4, 20, 20, 2], bc_filename = 'whole_cylinder.bc') simu = Simulation() simu.read_solver_input('whole_cylinder.msh') simu.domain.read_mesh_file('whole_cylinder.msh', True) inter = Interpreter() eq = inter.build_static_EM_eq(simu) g = eq['sol_vec'] my_solver = Solver() fields = my_solver.solve_stationary(simu, eq) quads = my_solver.substract_1(simu.domain.elements.quads.el_set) quads = quads[:,1:] from numpy import zeros field3 = zeros((simu.domain.nodes.n,3)) field3[:,0:2] = fields
glo_tag = 'hexagon' # Global tag for referencing all files nodes, elements = read_mesh(glo_tag +'.msh') n = shape(nodes)[0] #Number of nodes bc_lines = elements[1] # Boundary condition is (bc) lines triangles = elements[2] potential = potential_2d('well', nodes, v0 = 2) write_solver_input(glo_tag +'.msh', parameter = potential, dimension = 2, \ bc_type = 'Dir', \ sol_type = 'Stationary', eq = 'Schro', \ analysis_param = ['y', 'y', 4, 20, 15, 15, 1], \ bc_filename = glo_tag+'.bc') k = read_solver_input(glo_tag +'.msh') v, solution = schroedinger(glo_tag +'.msh') triangles = substract_1(triangles) triangles = triangles[:, 1:] #k, solution = schroedinger(glo_tag +'.msh') #z = zeros((k[0].shape[0], 3)) #print k[0].shape, z[:, 0:1].shape #z[:, 0:2] = k[0] #nodes = z #triangles = k[1]
from math import pi glo_tag = "circle2" # Global tag for referencing all files nodes, elements = read_mesh(glo_tag + ".msh") n = shape(nodes)[0] # Number of nodes bc_lines = elements[1] # Boundary condition is (bc) lines triangles = elements[2] potential = potential_2d("well", nodes, v0=0) write_solver_input( glo_tag + ".msh", parameter=potential, dimension=2, bc_type="Dir", sol_type="Stationary", eq="Schro", analysis_param=["y", "y", 20, 20, 15, 15, 1], bc_filename=glo_tag + ".bc", ) k = read_solver_input(glo_tag + ".msh") v, solution = schroedinger(glo_tag + ".msh") triangles = substract_1(triangles) triangles = triangles[:, 1:] # k, solution = schroedinger(glo_tag +'.msh') # z = zeros((k[0].shape[0], 3)) # print k[0].shape, z[:, 0:1].shape # z[:, 0:2] = k[0] # nodes = z
# -*- coding: utf-8 -*- """ Created on Tue Mar 19 11:31:57 2013 @author: santiago """ from Classes import Simulation from Interpreter import Interpreter from Solver import Solver from write import write_vtk, write_solver_input write_solver_input('square8_cap.msh',dimension = 2, bc_type = 'Dir', \ parameter = [], eq = 'Harm_Elec', sol_type = 'Stationary',analysis_param \ = ['y', 'y', 4, 4, 20, 20, 2], bc_filename = 'square.bc') simu = Simulation() simu.read_solver_input('square8_cap.msh') simu.domain.read_mesh_file('square8_cap.msh',simu) inter = Interpreter() eq = inter.build_static_EM_eq(simu) my_solver = Solver() fields = my_solver.solve_stationary(simu, eq) quads = my_solver.substract_1(simu.domain.elements.quads.el_set) quads = quads[:,1:] from numpy import zeros field3 = zeros((simu.domain.nodes.n,3)) field3[:,0:2] = fields fields = field3
from inform import inform glo_tag = 'square2' # Global tag for referencing all files nodes, elements = read_mesh(glo_tag +'.msh') n = shape(nodes)[0] #Number of nodes bc_lines = elements[1] # Boundary condition is (bc) lines triangles = elements[2] potential = potential_2d('well', nodes, v0 = 0) write_solver_input(glo_tag +'.msh', parameter = potential, dimension = 2, \ bc_type = 'Bloch', \ sol_type = 'Stationary', eq = 'Schro', \ analysis_param = ['y', 'n', 3, 1, 50, 50, 2], \ bc_filename = 'test2.bc') #k = read_solver_input(glo_tag +'.msh') #v, solution = schroedinger(glo_tag +'.msh') #triangles = substract_1(triangles) #triangles = triangles[:, 1:] k, solution = schroedinger(glo_tag +'.msh') z = zeros((k[0].shape[0], 3)) print k[0].shape, z[:, 0:1].shape z[:, 0:2] = k[0] nodes = z triangles = k[1]
def schroedinger(filename, nodes = 0, elements = 0, parameter = [], \ dimension = 1, bc_type = 'Dir', sol_type = 'Stationary', \ eq = 'Schro', analysis_param = ['y', 'y', 4, 4, 20, 20, 2], \ bc_filename = ''): """ Function Schroedinger computes the solution for Schroedinger equation using the Finite Element Method. For now it is able to solve the Stationary form with Dirichlet and Bloch boundary conditions in 1D. The function is made to be used either with direct assignment of the input parameters, or by reading those parameters from a file. Parameters: ----------- filename: String with the name of the file that contains the information regarding the geometry, mesh, border conditions, and other parameters necessary for the solution of the problem. This file is a modified Gmsh output file with extension .msh nodes: Numpy array matrix of nodes containing the coordinates of the nodes from the discretized domain. nodes is an array like matrix of dimension (n,3). Where each column represents the value of the nodes on one of the three coordinate axes x,y,z. elements: Numpy array matrix of elements containing the relations between nodes from the discretized domain. elements is an array like matrix of dimension (n_elements,2) in the case of 1D, and (n_elements,3) for 2D problems. parameter: Is an array that describes the potential actuating over the the elements of the domain given by elements. For each element in elements there is an associated potential value on the same position in the array parameter. The potential in Scroedinger equation defines the specific nature of the problem to be solved. For more details on how to define a potential and what does it mean pleas read the documentation of the Potential1D function in the module PrePro. dimension: int parameter that tells the program wether to solve for a 1D problem or a 2D problem. bc_type: String parameter for the selection of a border condition that can be either: 'Dir' For the Dirichlet border condition (Infinite potential well). 'Bloch' For the periodic formulation of the problem. (Electron in a periodic material ) sol_type: String that tells wether to solve the stationary version of the equation or another not yet suported. 'Stationary' analysis_param: Array that contains the information regarding the number of solutions to be computed and wether to save the values or not. analysis_param[0]: String answer to the question save Eigen Values? analysis_param[1]: String answer to the question save Eigen Vectors? analysis_param[2]: Integer number of Eigen Values to save analysis_param[3]: Integer number of Eigen Vectors to save analysis_param[4]: Integer number of wave numbers in x to sweep analysis_param[5]: Integer number of wave numbers in y to sweep analysis_param[6]: biggest value of k. it may be the lenght of the dommain Last modification: date 16/11/2011 """ #------------------------ Load from file if given ------------------------- assert isinstance(filename, str) if filename != '': # If type is not blank solver_input = read_solver_input(filename) # Import input parameters for if solver_input != []: dimension = solver_input[0] bc_type = solver_input[1] parameter = solver_input[2] # Reasign eq = solver_input[3] sol_type = solver_input[4] analysis_param = solver_input[5] # the solution bc_filename = solver_input[6] # If the file does not contain solution parameters, the ones given as # arguments of the function are written in the file. else: write_solver_input(filename, dimension = dimension, bc_type = bc_type, sol_type = sol_type, \ eq = eq, parameter = parameter, \ bc_filename = bc_filename) nodes, elements = read_mesh(filename) # Import nodes and elements n = shape(nodes)[0] #Number of nodes # el_points = elements[0] bc_lines = elements[1] # Boundary condition is (bc) lines if dimension == 2: triangles = elements[2] #------------------------------ 1D problem ------------------------------- # Reinterpretation of the parameter as the potential v = parameter if dimension == 1: K, M = mat_assembly_1d(nodes, n, v) #---------------------- With dirichlet boundary conditions ------------ if 'Dir' in bc_type and 'Stationary' in sol_type: # These two matrices are called the Dirichlet matrices # of both the stiffness equivalent and mass equivalent matrices. Kd = K[1:n-1, 1:n-1] Md = M[1:n-1, 1:n-1] print 'K shape is:\n', K.shape if 'y'in analysis_param[0] and 'n' in analysis_param[1]: n_vals = int(analysis_param[2]) v = linalg.eigvalsh(Kd, Md, eigvals = (0, n_vals-1)) # v = v/2 print 'The Eigenvalues are:\n', v return v elif 'y'in analysis_param[0] and 'y'in analysis_param[1]: n_vals = int(analysis_param[2]) n_vects = int(analysis_param[3]) n_solutions = max(n_vals,n_vects) v, Dd = linalg.eigh(Kd, Md, eigvals = (0, n_solutions-1)) # v = v/2 print 'The Eigenvalues are:\n', v E1=zeros(4) for i in range(0,4): E1[i]=(i+1)**2*pi**2/((2*pi)**2) error=linalg.norm(E1-v)/linalg.norm(E1) print 'error', error D = zeros((n, n_vects)) print 'D', D.shape, 'Dd', Dd.shape D[1:n-1, :] = Dd return v, D elif 'n' in analysis_param[0] and 'y' in analysis_param[1]: n_vects = int(analysis_param[3]) v, Dd = linalg.eigh(Kd, Md, eigvals = (0, n_vects-1)) D = zeros((n, n_vects)) D[1:n-1, :] = Dd return D else: print 'error: If you dont want anything why do you solve?' #----------------- With Bloch periodic boundary conditions ------------ elif 'Bloch' in bc_type: import cmath from numpy import asarray K = asarray(K, dtype = complex) M = asarray(M, dtype = complex) print 'K shape is:\n', K.shape # Bloch analysis parameters xi = nodes[0, 0] # initial x xf = nodes[n-1, 0] # final x n_vals = int(analysis_param[2]) # number of eigenvales to compute nk = int(analysis_param[4]) # number of k to sweep kmax = 4.*pi/xf kmin = -0.0 k_range = linspace(kmin, kmax, num = nk) omega = zeros( (len(k_range), n_vals) ) E = zeros( (len(k_range), n_vals) ) print 'Number of eigenvales to compute: ', n_vals, \ '\nNumber of wave numbers to sweep: ', nk, \ ' in ', [k_range[0],k_range[nk-1]] # Bloch-Periodicity imposition ll = 0 Kaux = K.copy() Maux = M.copy() for k in k_range: # Loop over the different wave numbers k fi = cmath.exp(1.0j*k*xi) ff = cmath.exp(1.0j*k*xf) K = Kaux.copy() M = Maux.copy() for i in range(0, n): K[0, i] = K[0, i]*fi.conjugate() K[i, 0] = K[i, 0]*fi K[n-1, i] = K[n-1, i]*ff.conjugate() K[i, n-1] = K[i, n-1]*ff M[0, i] = M[0, i]*fi.conjugate() M[i, 0] = M[i, 0]*fi M[n-1 , i] = M[n-1, i]*ff.conjugate() M[i, n-1] = M[i, n-1]*ff K[n-1, :] = K[0, :] + K[n-1, :] K[:, n-1] = K[:, 0] + K[:, n-1] M[n-1, :] = M[0, :] + M[n-1, :] M[:, n-1] = M[:, 0] + M[:, n-1] Kd = K[1:n, 1:n] Md = M[1:n, 1:n] vals = linalg.eigvalsh(Kd, Md, eigvals = (0, n_vals-1) ) for i in range(0, n_vals): omega[ll, i] = sqrt( abs(vals[i]) ) for i in range(0, n_vals): E[ll, i] = vals[i] ll = ll + 1 plt.figure(2) plt.hold(True) legend = [] for i in range(0,n_vals): plt.plot(k_range, E[:, i]) legend.append('n = '+str(i+1)) plt.plot(k_range, (k_range)**2, '--k') legend.append('Free Electron') plt.title('Dispersion relation') plt.legend(legend,loc=2) plt.xlabel('Nondimensional wave number - $a\kappa/\pi$') plt.ylabel('Nondimensional energy - $2ma^2E/\hslash^2$') plt.xlim(xmax=2) plt.grid() plt.show() else: print 'Only Dirichlet and Bloch for now, sorry' #------------------------------ 2D problem ------------------------------- elif dimension == 2: from matrices import global_stiffness_matrix, global_mass_matrix, \ global_potential_matrix from vectors import dirichlet_vector, build_solution h = 1. m = 1. print 'Building matrices...\n' boundary = read_bc(bc_filename)# Read boundary conditions from .bc file #===================== Build stiffness matrix ================== stif = global_stiffness_matrix(nodes, triangles) stif = h/(2.*m)*stif #---------------------- With dirichlet boundary conditions ------------ if 'Dir' in bc_type and 'Stationary' in sol_type: dirichlet = boundary[0] # Dirichlet conditions are the first list #===================== Build vectors =========================== stif_d, d, remove, g = dirichlet_vector(bc_lines, dirichlet, \ stif) # ==================== Build mass matrix ======================= mass_d = global_mass_matrix(nodes, triangles, remove) #===================== Build potential matrix ================== v_d = global_potential_matrix(nodes, triangles, v, remove) # print "nodes",nodes # print "stif",stif # print "mass",mass_d # print "v_d", v_d print 'Solving eigenvalue problem...\n' if 'y'in analysis_param[0] and 'n' in analysis_param[1]: n_vals = int(analysis_param[2]) v = linalg.eigvalsh(stif_d + v_d, mass_d, \ eigvals = (0, n_vals-1)) # v = v/2 print 'The Eigenvalues are:\n', v return v elif 'y'in analysis_param[0] and 'y'in analysis_param[1]: n_vals = int(analysis_param[2]) n_vects = int(analysis_param[3]) n_solutions = max(n_vals,n_vects) v, dir_solution = linalg.eigh(stif_d + v_d, mass_d, \ eigvals = (0, n_solutions-1)) # v = v/2 solution = zeros((n, n_vects)) for i in range(n_vects): solution[:,i] = build_solution(dir_solution[:, i], g, remove) return v, solution elif 'n'in analysis_param[0] and 'y'in analysis_param[1]: n_vects = int(analysis_param[3]) v, dir_solution = linalg.eigh(stif_d + v_d, mass_d, \ eigvals = (0, n_vects-1)) solution = zeros((n, n_vects)) for i in range(n_vects): solution[:,i] = build_solution(dir_solution[:, i], g, remove) return solution else: print 'error: If you dont want anything why do you solve?' #---------------------- With Bloch boundary conditions ------------ elif 'Bloch' in bc_type and 'Stationary' in sol_type: from numpy import asarray,vstack from vectors import reference_image_bloch_vectors from utils import bloch_multiplication, bloch_sum # ==================== Build mass matrix ======================= mass = global_mass_matrix(nodes, triangles) #===================== Build potential matrix ==================== v = global_potential_matrix(nodes, triangles, v) #================ Convert to complex matrices ==================== stif = asarray(stif, dtype = complex) mass = asarray(mass, dtype = complex) v = asarray(v, dtype = complex) #===== Sum kinetic and potential matrices of the Hamiltonian ====== stif = stif + v #= Retrieve the list of image and reference bloch boundary nodes == bloch = boundary[2] ref_im = reference_image_bloch_vectors(bc_lines, bloch) #============= Discretize the wavenumber dommain ================== nk_x = int(analysis_param[4]) # number of k to sweep in x nk_y = int(analysis_param[5]) # number of k to sweep in y k_max = pi/float(analysis_param[6]) k_min = -k_max k_range_x = linspace(k_min, k_max, num = nk_x) k_range_y = linspace(k_min, k_max, num = nk_y) n_vals = int(analysis_param[2]) #================ Initiate global variable ======================= energy = zeros( (nk_x * nk_y, n_vals) ) # print 'Number of eigenvales to compute: ', n_vals, \ # '\nNumber of wave numbers to sweep: ', 'in x: ', nk_x, \ # ' and in y: ', nk_y, ' in ', \ # [k_range_x[0],k_range_x[nk_x-1]], \ # [k_range_y[0],k_range_y[nk_y-1]], '\n' #======== Defin<xe a new image reference =========================== ref_im_aux = ref_im[0] # image(im) reference(ref) for complex # multimplication (mul) operations for bl in range(1, len(ref_im)): ref_im_aux = vstack((ref_im_aux, ref_im[bl])) #=============== Find who are the corners ======================= for corner in list(ref_im_aux[:, 0]): if list(ref_im_aux[:, 0]).count(corner) == 2: break for corner2 in list(ref_im_aux[:, 1]): if list(ref_im_aux[:, 1]).count(corner2) == 2: break #==== Relate the corners and delete their previous links=========== im_mul = list(set(list(ref_im_aux[:, 1]))) ref_mul = [] for i in im_mul: ref_mul.append(list(ref_im_aux[:, 0])[list(ref_im_aux[:, 1]).index(i)]) ref_im_mul = array([ref_mul, im_mul]).T # Rearranged without # repeated reference # to corner # ref_im_sum = ref_im_mul # from numpy import delete # for i in range(2):#Delete the links between conrner2 and other nodes # ref_im_sum=delete(ref_im_sum, list(ref_im_sum[:, 1]).index(corner2), 0) # # Make corner2 the image of corner # ref_im_sum[list(ref_im_mul[:, 0]).index(corner), 1] = corner2 ref_im_mul[list(ref_im_mul[:, 1]).index(corner2), 0] = corner print "ref_im_mul", ref_im_mul #======================= Main cycles =============================== i = 0 print 'Calculating each of the ', nk_x * nk_y, \ ' points in k plane...\n' for k_x in k_range_x: # Loop over the different wave numbers k in x for k_y in k_range_y: # Loop over the different wave numbers k in y # Multiply boundary nodes of each matrix by phase factor new_stif, new_mass = bloch_multiplication(k_x, \ k_y, nodes, \ ref_im_mul, stif.copy(), \ mass.copy()) new_stif, new_mass = bloch_sum(ref_im_mul, new_stif, new_mass) vals = linalg.eigvalsh(new_stif, new_mass, \ eigvals = (0, n_vals-1)) for val in range(0, n_vals): energy[i, val] = vals[val] print i+1, ' points out of :', nk_x * nk_y, '\n' i = i+1 from meshUtils import meshtr2D k_mesh = meshtr2D(k_min, k_max, k_min, k_max, nk_x, nk_y) return k_mesh, energy #------------------ If they ask for something we don't have----------- else: print 'Hang on, we are currently working on more options.' else: print 'Only 1D and 2D for now. Sorry' print 'done'