def console_output(self, xopt, image_file): self.topology_factory.update_topology(xopt) tup = (2*self.topology_factory.a, 2*self.topology_factory.b) print('The element dimensions are (um): %gx%g' % tup) params = self.topology_factory.get_params() cantilever = microfem.Cantilever(*params) microfem.plot_topology(cantilever, image_file) if self.topology_factory.is_connected is True: fem = microfem.PlateFEM(self.material, cantilever) coords = (cantilever.xtip, cantilever.ytip) opr = microfem.PlateDisplacement(fem, coords).get_operator() mode_ident = microfem.ModeIdentification(fem, cantilever, 'plate') w, _, vall = fem.modal_analysis(self.n_modes) freq = np.sqrt(w) / (2*np.pi) kuu = fem.get_stiffness_matrix(free=False) phis = [vall[:, [i]] for i in range(self.n_modes)] wtips = [opr @ p for p in phis] kfunc = lambda p, w: np.asscalar(p.T @ kuu @ p / w ** 2) ks = [kfunc(p, w) for p, w in zip(phis, wtips)] types = [mode_ident.is_mode_flexural(p) for p in phis] tup = ('Disp', 'Freq (Hz)', 'Stiffness', 'Flexural') print('\n %-15s %-15s %-15s %-10s' % tup) for i in range(self.n_modes): tup = (i, wtips[i], freq[i], ks[i], str(types[i])) print('%-2d: %-15g %-15g %-15g %-10s' % tup) for i in range(self.n_modes): microfem.plot_mode(fem, vall[:, i])
def objective_function(self, xs): self.topology_factory.update_topology(xs) if self.topology_factory.is_connected is True: params = self.topology_factory.get_params() cantilever = microfem.Cantilever(*params) fem = microfem.PlateFEM(self.material, cantilever) coords = (cantilever.xtip, cantilever.ytip) opr = microfem.PlateDisplacement(fem, coords).get_operator() mode_ident = microfem.ModeIdentification(fem, cantilever, 'plate') try: w, _, vall = fem.modal_analysis(1) except RuntimeError: print('singular') kuu = fem.get_stiffness_matrix(free=False) f1 = np.asscalar(np.sqrt(w) / (2 * np.pi)) phi1 = vall[:, [0]] wtip1 = np.asscalar(opr @ phi1) kfunc = lambda p, w: np.asscalar(p.T @ kuu @ p / w**2) k1 = kfunc(phi1, wtip1) type1 = mode_ident.is_mode_flexural(phi1) if type1 is False: cost = 1e8 else: cost = -f1 * 1e-6 if k1 < self.k1 else k1 return (cost, ) return (self.topology_factory.connectivity_penalty, )
def objective_function(self, xs): self.topology_factory.update_topology(xs) a = self.topology_factory.a b = self.topology_factory.b if self.topology_factory.is_connected is True: topology = self.topology_factory.topology cantilever = microfem.Cantilever(topology, a, b) fem = microfem.PlateFEM(self.material, cantilever) coords = (cantilever.xtip, cantilever.ytip) opr = PlateDisplacement(fem, coords).get_operator() mode_ident = ModeIdentification(fem, cantilever) w, _, vall = fem.modal_analysis(self.n_modes) kuu = fem.get_stiffness_matrix(free=False) phi = vall[:, [0]] wtip = opr @ phi f1 = np.asscalar(np.sqrt(w) / (2 * np.pi)) k1 = np.asscalar(phi.T @ kuu @ phi / wtip**2) type_ = mode_ident.is_mode_flexural(phi) cost = (-f1, k1) if type_ is True else (1e8, 1e8) return cost return (self.topology_factory.connectivity_penalty, self.topology_factory.connectivity_penalty)
def objective_function(self, xs): self.topology_factory.update_topology(xs) if self.topology_factory.is_connected is True: params = self.topology_factory.get_params() cantilever = microfem.Cantilever(*params) fem = microfem.PlateFEM(self.material, cantilever) coords = (cantilever.xtip, cantilever.ytip) opr = microfem.PlateDisplacement(fem, coords).get_operator() mode_ident = microfem.ModeIdentification(fem, cantilever, 'plate') w, _, vall = fem.modal_analysis(self.n_modes) kuu = fem.get_stiffness_matrix(free=False) fs = np.sqrt(w) / (2*np.pi) phis = [vall[:, [i]] for i in range(self.n_modes)] wtips = [opr @ p for p in phis] kfunc = lambda p, w: np.asscalar(p.T @ kuu @ p / w ** 2) ks = [kfunc(p, w) for p, w in zip(phis, wtips)] types = [mode_ident.is_mode_flexural(p) for p in phis] if types[0] is False: cost = 1e8 elif types[1] is True: cost = self.evaluation(fs[0], fs[1], ks[0], ks[1]) elif types[2] is True: cost = self.evaluation(fs[0], fs[2], ks[0], ks[2]) else: cost = 2e7 return (cost,) return (self.topology_factory.connectivity_penalty,)
def console_output(self, xopt, image_file): self.topology_factory.update_topology(xopt) topology = self.topology_factory.topology cantilever = microfem.Cantilever(topology, self.a, self.b) microfem.plot_topology(cantilever, image_file) if self.topology_factory.is_connected is True: fem = microfem.PlateFEM(self.material, cantilever) coords = (cantilever.xtip, cantilever.ytip) opr = PlateDisplacement(fem, coords).get_operator() mode_ident = ModeIdentification(fem, cantilever) w, _, vall = fem.modal_analysis(self.n_modes) freq = np.sqrt(w) / (2*np.pi) kuu = fem.get_stiffness_matrix(free=False) phis = [vall[:, [i]] for i in range(self.n_modes)] wtips = [opr @ p for p in phis] ks = [np.asscalar(p.T @ kuu @ p / w ** 2) for p, w in zip(phis, wtips)] costs = [k / ks[0] for k in ks] types = [mode_ident.is_mode_flexural(p) for p in phis] tup = ('Disp', 'Freq (Hz)', 'Stiffness', 'Ratio', 'Flexural') print('\n %-15s %-15s %-15s %-15s %-10s' % tup) for i in range(self.n_modes): tup = (i, wtips[i], freq[i], ks[i], costs[i], str(types[i])) print('%-2d: %-15g %-15g %-15g %-15g %-10s' % tup) for i in range(self.n_modes): microfem.plot_mode(fem, vall[:, i])
def objective_function(self, xs): """ Evaluates the objective function. The objective function calculates the ratio between the dynamic stiffness of the flexural modes with respect to the first. Parameters ---------- xs : list of floats The optimization design variables for a solution. Returns ------- : float The evaluated objective for the solution. """ self.topology_factory.update_topology(np.array(xs)) topology = self.topology_factory.topology if self.topology_factory.is_connected is True: cost = self.problem.objective_function(topology) # Initialize new FEM and other analyses. cantilever = microfem.Cantilever(topology, self.a, self.b) self.fem.update_mesh(cantilever) coords = (cantilever.xtip, cantilever.ytip) pd = PlateDisplacement(self.fem, coords) opr = pd.get_operator() mode_ident = ModeIdentification(self.fem, cantilever) # Perform modal analysis and retrieve the stiffness matrix. w, _, vall = self.fem.modal_analysis(self.n_modes) kuu = self.fem.get_stiffness_matrix(free=False) # Analyze the first mode. phi1 = vall[:, [0]] wtip1 = opr @ phi1 k1 = np.asscalar(phi1.T @ kuu @ phi1 / wtip1**2) cost, ratio_index, ratios = 0, 0, [2, 3, 4] for i in range(1, self.n_modes): if ratio_index < (self.n_ratio - 1): phi = vall[:, [i]] if mode_ident.is_mode_flexural(phi) == True: wtip = opr @ phi k = np.asscalar(phi.T @ kuu @ phi / wtip**2) cost += (k / k1 - ratios[ratio_index])**2 ratio_index += 1 return (cost, ) return (self.topology_factory.connectivity_penalty, )
def console_output(self, xopt, image_file): self.topology_factory.update_topology(xopt) params = self.topology_factory.get_params() cantilever = microfem.Cantilever(*params) microfem.plot_topology(cantilever, image_file) if self.topology_factory.is_connected is True: fem = microfem.PlateFEM(self.material, cantilever) w, _, vall = fem.modal_analysis(1) f = np.asscalar(np.sqrt(w) / (2 * np.pi)) print('The first modal frequency is (Hz): %g' % f) microfem.plot_mode(fem, vall[:, 0])
def objective_function(self, xs): self.topology_factory.update_topology(xs) if self.topology_factory.is_connected is True: params = self.topology_factory.get_params() cantilever = microfem.Cantilever(*params) fem = microfem.PlateFEM(self.material, cantilever) w, _, _ = fem.modal_analysis(1) f = np.asscalar(np.sqrt(w) / (2 * np.pi)) cost = abs(f - self.f0) return (cost, ) return (self.topology_factory.connectivity_penalty, )
def to_console_final(self, xopt): print() print('--- Solution Characteristics ---') if self.exe_time != 0: print('Time (s): %g' % (self.exe_time)) self.topology_factory.update_topology(xopt) topology = self.topology_factory.topology cantilever = microfem.Cantilever(topology, self.a, self.b) fn = ''.join((self.dir, '/', self.tag, '-image.png')) microfem.plot_topology(cantilever, fn) if self.topology_factory.is_connected is True: self.fem.update_mesh(cantilever) coords = (cantilever.xtip, cantilever.ytip) opr = PlateDisplacement(self.fem, coords).get_operator() mode_ident = ModeIdentification(self.fem, cantilever) w, _, vall = self.fem.modal_analysis(self.n_modes) freq = np.sqrt(w) / (2 * np.pi) kuu = self.fem.get_stiffness_matrix(free=False) phis = [vall[:, [i]] for i in range(self.n_modes)] wtips = [opr @ p for p in phis] ks = [ np.asscalar(p.T @ kuu @ p / w**2) for p, w in zip(phis, wtips) ] costs = [k / ks[0] for k in ks] types = [mode_ident.is_mode_flexural(p) for p in phis] tup = ('Disp', 'Freq (Hz)', 'Stiffness', 'Ratio', 'Flexural') print('\n %-15s %-15s %-15s %-15s %-10s' % tup) for i in range(self.n_modes): tup = (i, wtips[i], freq[i], ks[i], costs[i], str(types[i])) print('%-2d: %-15g %-15g %-15g %-15g %-10s' % tup) for i in range(self.n_modes): microfem.plot_mode(self.fem, vall[:, i])
#params = {'nelx': 30, 'nely': 60, 'a0': 10e-6, 'b0':10e-6} #top = PowerTopology(params) #params = {'nelx': 30, 'nely': 60, 'a0': 5e-6, 'b0':5e-6} #top = NewRectangleTopology(params) #top = NewSplitTopology(params) #top = NewSteppedTopology(params) #top = NewPowerTopology(params) #top = NewTwoStructuresTopology(params) params = { 'support_ratio': 3.0, 'nknx': 5, 'nkny': 10, 'nelx': 40, 'nely': 80, 'pcon1': 1.0e7, 'pcon2': 1.0e3, 'a0': 5.0e-6, 'b0': 5.0e-6 } top = NewCompactTopology(params) for i in range(1): xs = 2 * np.random.random(top.ind_size) - 1.0 top.update_topology(xs) cantilever = microfem.Cantilever(*top.get_params()) #print(xs) print(top.xtip, top.ytip) microfem.plot_topology(cantilever)
# Along with the topology, the size of each element needs to be defined. `a` # is half the element width in the x-direction (rows) and `b` is half the # element length in the y-direction (cols). The units are in um. a = 5 b = 5 # One option for normalising the mode shapes is to normalize with respect to # the deflection at a point on the cantilever. The coordinates are in um and # should be on a solid element. xtip = 250 ytip = 495 # Combine the above parameters into a Cantilever object in the microfem # package. Information about the cantilever can be displayed and the topology # can be plotted. cantilever = microfem.Cantilever(topology, a, b, xtip, ytip) cantilever.to_console() microfem.plot_topology(cantilever) material = microfem.PiezoMumpsMaterial() fem = microfem.LaminateFEM(material, cantilever) # With the FEM model buitl, modal analysis can be performed. This returns the # resonance frequencies and mode shapes of the cantilever. These can then be # plotted. n_modes = 3 ws, _, vall = fem.modal_analysis(n_modes=n_modes) # Using the results of the modal analysis, the frequency, stiffness, # tip displacement, and mode type (flexural, torsional), can be determined. coords = (cantilever.xtip, cantilever.ytip)