def create_stiffness_maps(folder, delta, outfolder='stiffness-maps', k0=1645, eps_s=0.0075, d_s=0.033, d_0=0.0008, radius=2, i_max=None): """ Creates 2D stiffness maps for a time series. (and single plot with mean and maximal stiffness for eacht time step) folder: containing the defromation series (output folder of compute_displacement_series) outfolder: output of Strain maps delta: Windowsize (px) as it was used in the evaluation of deformations for correct strain radius: used to smooth the deformation field i_max: can be used to evaluate only first i timesteps k0, eps_s,d_s,_do: material parameters to compute the stiffness """ # creates folder if it doesn't exist if not os.path.exists(outfolder): os.makedirs(outfolder) # creates folder if it doesn't exist if not os.path.exists(os.path.join(outfolder, "plots")): os.makedirs(os.path.join(outfolder, "plots")) # fiber material material = SemiAffineFiberMaterial(k0, d_0, eps_s, d_s) # loead extensional stress data and get stiffness - might need to adjust range epsilon = np.arange(-1, 1.9, 0.0001) x, y = macro.getExtensionalRheometerStress(epsilon, material) get_stiffness = interpolate.interp1d(x[1:], (y[1:] - y[:-1]) / (x[1:] - x[:-1])) # load in displacement data and ssheroid mask dis_files = natsorted(glob(folder + '/dis*.npy')) seg_files = natsorted(glob(folder + '/seg*.npy')) dis = np.load(dis_files[0], allow_pickle="True").item() x_rav, y_rav = np.ravel(dis['x']), np.ravel(dis['y']) u_rav, v_rav = np.zeros_like(np.ravel(dis['u'])), np.zeros_like( np.ravel(dis['v'])) # take all timesteps if not specified if not i_max: i_max = len(dis_files) # loop over all times median_stiffness = [] max_stiffness = [] for i in tqdm(range(i_max)): # get displacement field dis = np.load(dis_files[i], allow_pickle="True").item() u_rav += np.ravel(dis['u']) v_rav += np.ravel(dis['v']) seg = np.load(seg_files[i], allow_pickle="True").item() x_sph, y_sph = seg['centroid'] dist, angle, displ = get_displ(x_rav, y_rav, u_rav, v_rav, x_sph, y_sph) # make sure spheroid mask is visible at the end dist[np.isnan(u_rav)] = np.nan # smooth displacement field displ = displ.reshape(dis['x'].shape).copy() displ = generic_filter(displ, np.nanmean, footprint=disk(radius), mode='nearest') # linear interpolation of discrete displacement field displ = np.ravel(displ) x, y = np.ravel(dis['x']), np.ravel(dis['y']) mask = ~(np.isnan(x) | np.isnan(y) | np.isnan(displ)) x2 = x[mask] y2 = y[mask] displ2 = displ[mask] f = LinearNDInterpolator(np.array([x2, y2]).T, displ2) # compute strain x_old = (dist * np.cos(angle) + x_sph).reshape(dis['x'].shape) y_old = (dist * np.sin(angle) + y_sph).reshape(dis['y'].shape) dist_old = f(x_old, y_old) x_new = ((dist + delta) * np.cos(angle) + x_sph).reshape( dis['x'].shape) y_new = ((dist + delta) * np.sin(angle) + y_sph).reshape( dis['y'].shape) dist_new = f(x_new, y_new) strain = 1 + (dist_old - dist_new) / delta # compute stiffening stiffness = get_stiffness(strain) log_stiffness = np.log10(stiffness) #stiffness = np.zeros_like(strain) + np.nan # initalize with linear stiffness #stiffness[strain <= 0] = k0 * np.exp(strain[strain <= 0] / d_0) # buckling #stiffness[(strain > 0) & (strain < eps_s)] = k0 # linear regime #stiffness[strain >= eps_s] = k0 * np.exp((strain[strain >= eps_s] - eps_s) / d_s) # strain stiffening # plot result plt.figure(figsize=(8, 6)) height = log_stiffness.shape[0] width = log_stiffness.shape[1] plt.imshow(log_stiffness, vmin=2, vmax=4, cmap='inferno', extent=[0, width, height, 0], origin='lower') cb = plt.colorbar(fraction=0.025, label='Matrix stiffness', ticks=np.log10( [100, 250, 500, 1000, 2500, 5000, 10000])) cb.ax.set_yticklabels([ '$\mathregular{\leq}$ 100 Pa', '250 Pa', '500 Pa', '1.0 kPa', '2.5 kPa', '5.0 kPa', '$\mathregular{\geq}$ 10.0 kPa' ]) plt.xlim((0, width)) plt.ylim((0, height)) plt.axis('off') plt.gca().get_xaxis().set_visible(False) plt.gca().get_yaxis().set_visible(False) plt.tight_layout() plt.savefig(outfolder + '/stiffening' + str(i + 1).zfill(6) + '.png', dpi=250) print('') print("Max. Stiffness: " + str(np.nanmax(stiffness))) print('') median_stiffness.append(np.nanmedian(stiffness)) max_stiffness.append(np.nanmax(stiffness)) plt.close() # plot and save overview np.savetxt( os.path.join(outfolder, "plots") + '/median_stiffness.txt', median_stiffness) np.savetxt( os.path.join(outfolder, "plots") + '/max_stiffness.txt', max_stiffness) # median stiffness plt.figure(figsize=(6, 2)) plt.grid() plt.xlabel("timesteps") plt.ylabel("median stiffness") plt.plot(median_stiffness) plt.tight_layout() plt.savefig(os.path.join(outfolder, "plots") + '/median_stiffness.png', dpi=300) plt.close() # max stiffness plt.figure(figsize=(6, 2)) plt.grid() plt.xlabel("timesteps") plt.ylabel("max. stiffness") plt.plot(max_stiffness) plt.tight_layout() plt.savefig(os.path.join(outfolder, "plots") + '/max_stiffness.png', dpi=300) plt.close() return
def spherical_contraction_solver(meshfile, outfolder, pressure, material, r_inner=None, r_outer=None, logfile=False, initial_displacenemts=None, max_iter=600, step=0.0033, conv_crit=0.01): coords, tets, r_inner, r_outer = read_meshfile(meshfile, r_inner, r_outer) # read in material parameters K_0 = material['K_0'] D_0 = material['D_0'] L_S = material['L_S'] D_S = material['D_S'] # create output folder if it does not exist, print warning otherwise if not os.path.exists(outfolder): os.makedirs(outfolder) else: print('WARNING: Output folder already exists! ({})'.format(outfolder)) # Initialize saenopy solver opbject M = Solver() material_saenopy = SemiAffineFiberMaterial(K_0, D_0, L_S, D_S) M.setMaterialModel(material_saenopy) M.setNodes(coords) M.setTetrahedra(tets) # define boundary conditions distance = np.sqrt(np.sum(coords**2., axis=1)) mask_inner = distance < r_inner * 1.001 mask_outer = distance > r_outer * 0.999 # Save Node Density at inner and outer sphere # Area per inner node A_node_inner = (np.pi * 4 * (r_inner)**2) / np.sum(mask_inner) # simple sqrt as spacing inner_spacing = np.sqrt(A_node_inner) # Area per outer node A_node_outer = (np.pi * 4 * (r_outer)**2) / np.sum(mask_outer) # simple sqrt as spacing outer_spacing = np.sqrt(A_node_outer) print('Inner node spacing: ' + str(inner_spacing * 1e6) + 'µm') print('Outer node spacing: ' + str(outer_spacing * 1e6) + 'µm') # displacements are everywhere NaN bcond_displacement = np.zeros((len(coords), 3)) * np.nan # except of a the outer border bcond_displacement[mask_outer] = 0 # forces are everywhere 0 bcond_forces = np.zeros((len(coords), 3)) # except at the outer boder there they are NaN bcond_forces[mask_outer] = np.nan # and at the innter border they depend on the pressure bcond_forces[mask_inner] = coords[mask_inner] bcond_forces[mask_inner] /= distance[mask_inner, None] A_inner = 4 * np.pi * r_inner**2. force_per_node = pressure * A_inner / np.sum(mask_inner) bcond_forces[mask_inner, :3] *= force_per_node # give the boundary conditions to the solver M.setBoundaryCondition(bcond_displacement, bcond_forces) if initial_displacenemts is not None: M.setInitialDisplacements(initial_displacenemts) # create info file with all relevant parameters of the simulation parameters = r"""K_0 = {} D_0 = {} L_S = {} D_S = {} PRESSURE = {} FORCE_PER_SURFACE_NODE = {} INNER_RADIUS = {} µm OUTER_RADIUS = {} µm INNER_NODE_SPACING = {} µm OUTER_NODE_SPACING = {} µm SURFACE_NODES = {} TOTAL_NODES = {}""".format(K_0, D_0, L_S, D_S, pressure, force_per_node, r_inner * 1e6, r_outer * 1e6, inner_spacing * 1e6, outer_spacing * 1e6, np.sum(mask_inner), len(coords)) with open(outfolder + "/parameters.txt", "w") as f: f.write(parameters) # solve the boundary problem M.solve_boundarycondition(stepper=step, i_max=max_iter, rel_conv_crit=conv_crit, relrecname=outfolder + "/relrec.txt") #, verbose=True M.save(outfolder + "/solver.npz")
#!/usr/bin/env python # coding: utf-8 get_ipython().run_line_magic('matplotlib', 'inline') import numpy as np import matplotlib.pyplot as plt from saenopy import macro from saenopy.materials import SemiAffineFiberMaterial material = SemiAffineFiberMaterial(900, 0.0004, 0.0075, 0.033) print(material) x, y = np.loadtxt("../macrorheology/data_exp/rheodata.dat").T plt.plot(x, y, "o", label="data") gamma = np.arange(0.005, 0.3, 0.0001) x, y = macro.getShearRheometerStress(gamma, material) plt.loglog(x, y, "-", lw=3, label="model") plt.xlabel("strain") plt.ylabel("shear stress [Pa]") plt.legend() import numpy as np import matplotlib.pyplot as plt from saenopy import macro from saenopy.materials import SemiAffineFiberMaterial
#!/usr/bin/env python # coding: utf-8 from saenopy import FiniteBodyForces # initialize the object M = FiniteBodyForces() from saenopy.materials import SemiAffineFiberMaterial # provide a material model material = SemiAffineFiberMaterial(1645, 0.0008, 0.0075, 0.033) M.setMaterialModel(material) import numpy as np # define the coordinates of the nodes of the mesh # the array has to have the shape N_v x 3 R = np.array([ [0., 0., 0.], # 0 [0., 1., 0.], # 1 [1., 1., 0.], # 2 [1., 0., 0.], # 3 [0., 0., 1.], # 4 [1., 0., 1.], # 5 [1., 1., 1.], # 6 [0., 1., 1.] ]) # 7 # define the tetrahedra of the mesh # the array has to have the shape N_t x 4
def cost(p): material = SemiAffineFiberMaterial(*params(p)) # print(material) return fit_error(np.log(func(gamma1, material)), data_shear1, weights1)
def plot_me(): material = SemiAffineFiberMaterial(*params(p)) plt.plot(data_shear1[:, 0], data_shear1[:, 1], "o", label="data") x, y = func(gamma1, material) plt.plot(x, y, "r-", lw=3, label="model")