def _setup_eit(self): mesh_t = self._mesh # ms, el_pos el_dist, step = 1, 1 ex_mat = eit_scan_lines(16, el_dist) # Reconstruction step eit_obj = greit.GREIT(mesh_t[0], mesh_t[1], ex_mat=ex_mat, step=step, perm=0.8, parser='std') # prem default value eq = 1. eit_obj.setup(p=0.45, lamb=1e-3, n=96, s=10.0, ratio=0.05) # n - wielkość siatki, domyślna wartość 32 return eit_obj
def current_matrix_generator(n_el: int, ex_mat_length: int, ex_pair_mode='adj', spaced: bool=False): """ This function generates an excitation matrix of current pairs using the adj method, opposite method, all possible pairs or custom step. It can iterate and build the matrix contiguously, assigning electrodes in turn around the perimeter or 'spaced' can be set to True, which spaces out the measurements slightly. I.e. for the adj method, spaced=True might give [(1,2),(5,6),(10,11)] as opposed to [(1,2),(2,3),(3,4)]. To Do: - Add in a randomly assigned current pairs method Parameters ---------- n_el : int The number of electrodes. ex_mat_length : int The desired length of the excitation matrix, if none will generate maximum number of measurements for the given ex_pair_mode. ex_pair_mode : int or string The default is 'adj' or step of 1, but can be 'opp' step of n_el/2 or 'all'. Also accepts a custom step value. spaced : bool, optional If True, this will activate orderedExMat which spaces out measurements around the perimeter. Returns ------- ex_mat : ndarray (N, 2) List of the current pairs (Source, sink). """ if (ex_pair_mode == 1 or ex_pair_mode == 'adj'): print("Adjacent current pairs mode") dist = 1 elif (ex_pair_mode == n_el//2 or ex_pair_mode == 'opp'): print("Opposite current pairs mode") dist = n_el//2 elif (ex_pair_mode == 'all'): print("All current pairs mode") elif (ex_pair_mode != 1 and ex_pair_mode != n_el//2 and (1 < ex_pair_mode < n_el-1)): print("Custom distance between current pairs. Dist:", ex_pair_mode) dist = ex_pair_mode else: print("Incorrect current pair mode selected. Function returning 0.") return 0 if (ex_pair_mode == 'all'): ex_mat = train.generateExMat(ne=n_el) elif spaced == True: ex_mat = train.orderedExMat(n_el=n_el, el_dist=dist) elif spaced == False: ex_mat = eit_scan_lines(ne=n_el, dist=dist) else: print("Something went wrong ...") if ex_mat_length is not None: ex_mat = ex_mat[0:ex_mat_length] return ex_mat
def set_pde(self): # construct mesh self.mesh_obj,self.el_pos=mesh.create(self.n_el, bbox=self.bbox, h0=self.meshsz) # extract node, element self.pts=self.mesh_obj['node'] self.tri=self.mesh_obj['element'] # initialize forward solver using the unstructured mesh object and the positions of electrodes self.fwd=Forward(self.mesh_obj, self.el_pos) # boundary condition self.ex_mat=eit_scan_lines(self.n_el,self.el_dist) # count PDE solving times self.soln_count = np.zeros(2)
# build tetrahedron # 3D tetrahedron must have a bbox bbox = [[-1, -1, -1], [1, 1, 1]] # save calling convention as distmesh 2D ms, el_pos = mesh.create(h0=0.15, bbox=bbox) no2xy = ms['node'] el2no = ms['element'] # report the status of the 2D mesh quality.stats(no2xy, el2no) """ 1. FEM forward simulations """ # setup EIT scan conditions el_dist, step = 7, 1 ex_mat = eit_scan_lines(16, el_dist) # calculate simulated data fwd = Forward(ms, el_pos) # in python, index start from 0 ex_line = ex_mat[1].ravel() # change alpha anomaly = [{'x': 0.40, 'y': 0.40, 'z': 0.0, 'd': 0.30, 'alpha': 100.0}] ms_test = mesh.set_alpha(ms, anomaly=anomaly, background=1.0) tri_perm = ms_test['alpha'] node_perm = pdeprtni(no2xy, el2no, np.real(tri_perm)) # solving once using fem f, _ = fwd.solve_once(ex_line, tri_perm)
# show fig, ax = plt.subplots(figsize=(6, 4)) im = ax.tripcolor(pts[:, 0], pts[:, 1], tri, np.real(perm), shading="flat", cmap=plt.cm.viridis) fig.colorbar(im) ax.axis("equal") ax.set_title(r"$\Delta$ Conductivities") plt.show() """ 2. calculate simulated data """ el_dist, step = 1, 1 ex_mat = eit_scan_lines(n_el, el_dist) fwd = Forward(mesh_obj, el_pos) f1 = fwd.solve_eit(ex_mat, step, perm=mesh_new["perm"], parser="std") """ 3. solve_eit using gaussian-newton (with regularization) """ # number of stimulation lines/patterns eit = jac.JAC(mesh_obj, el_pos, ex_mat, step, perm=1.0, parser="std") eit.setup(p=0.25, lamb=1.0, method="lm") # lamb = lamb * lamb_decay ds = eit.gn(f1.v, lamb_decay=0.1, lamb_min=1e-5, maxiter=20, verbose=True) # plot fig, ax = plt.subplots(figsize=(6, 4)) im = ax.tripcolor( pts[:, 0], pts[:, 1], tri,
no2xy = ms['node'] el2no = ms['element'] alpha = ms1['alpha'] - ms['alpha'] # show alpha fig, ax = plt.subplots(figsize=(6, 4)) im = ax.tripcolor(no2xy[:, 0], no2xy[:, 1], el2no, np.real(alpha), shading='flat') fig.colorbar(im) ax.axis('tight') ax.set_title(r'$\Delta$ Permitivity') """ 2. calculate simulated data using stack ex_mat """ el_dist, step = 7, 1 n_el = len(el_pos) ex_mat1 = eit_scan_lines(n_el, el_dist) ex_mat2 = eit_scan_lines(n_el, 1) ex_mat = np.vstack([ex_mat1, ex_mat2]) # forward solver fwd = Forward(ms, el_pos) f0 = fwd.solve(ex_mat, step, perm=ms['alpha']) f1 = fwd.solve(ex_mat, step, perm=ms1['alpha']) """ 3. solving using dynamic EIT """ # number of stimulation lines/patterns eit = jac.JAC(ms, el_pos, ex_mat=ex_mat, step=step, parser='std') eit.setup(p=0.40, lamb=1e-3, method='kotre') ds = eit.solve(f1.v, f0.v) """ 4. plot """
no2xy = ms['node'] el2no = ms['element'] alpha = ms1['alpha'] - ms['alpha'] # show alpha fig = plt.figure() plt.tripcolor(no2xy[:, 0], no2xy[:, 1], el2no, np.real(alpha), shading='flat') plt.colorbar() plt.title(r'$\Delta$ Permitivity') fig.set_size_inches(6, 4.5) """ 2. calculate simulated data using stack exMtx """ elDist, step = 7, 1 numEl = len(elPos) exMtx1 = eit_scan_lines(numEl, elDist) exMtx2 = eit_scan_lines(numEl, 1) exMtx = np.vstack([exMtx1, exMtx2]) # forward solver fwd = forward(ms, elPos) f0 = fwd.solve(exMtx, step, perm=ms['alpha']) f1 = fwd.solve(exMtx, step, perm=ms1['alpha']) """ 3. solving using dynamic EIT """ # number of excitation lines & excitation patterns eit = jac.JAC(ms, elPos, exMtx=exMtx, step=step, p=0.40, lamb=1e-3, parser='std', method='kotre') ds = eit.solve(f1.v, f0.v)
ms1 = mesh.set_alpha(ms, anom=anomaly, background=1.0) alpha = np.real(ms1['alpha'] - ms0['alpha']) # show alpha fig = plt.figure() plt.tripcolor(no2xy[:, 0], no2xy[:, 1], el2no, alpha, shading='flat', cmap=plt.cm.viridis) plt.colorbar() plt.title(r'$\Delta$ Conductivity') fig.set_size_inches(6, 4) plt.axis('equal') """ 2. FEM forward simulations """ # setup EIT scan conditions elDist, step = 1, 1 exMtx = eit_scan_lines(16, elDist) # calculate simulated data fwd = forward(ms, elPos) f0 = fwd.solve(exMtx, step=step, perm=ms0['alpha']) f1 = fwd.solve(exMtx, step=step, perm=ms1['alpha']) """ 3. Construct using GREIT """ eit = greit.GREIT(ms, elPos, exMtx=exMtx, step=step, parser='std', p=0.50, lamb=1e-4) ds = eit.solve(f1.v, f0.v) x, y, ds = eit.mask_value(ds, mask_value=np.NAN) # plot fig = plt.figure()
el2no = ms['element'] alpha = ms1['alpha'] # show fig = plt.figure() plt.tripcolor(no2xy[:, 0], no2xy[:, 1], el2no, np.real(alpha), shading='flat') plt.colorbar() plt.axis('equal') plt.title(r'$\Delta$ Conductivities') fig.set_size_inches((6, 4)) plt.show() """ 2. calculate simulated data """ elDist, step = 1, 1 exMtx = eit_scan_lines(numEl, elDist) fwd = forward(ms, elPos) f1 = fwd.solve(exMtx, step, perm=ms1['alpha']) """ 3. solve using gaussian-newton """ # number of excitation lines & excitation patterns eit = jac.JAC(ms, elPos, exMtx, step, perm=1.0, parser='std', p=0.25, lamb=1e-4, method='kotre') ds = eit.gn_solve(f1.v, maxiter=6, verbose=True) # plot fig = plt.figure() plt.tripcolor(no2xy[:, 0], no2xy[:, 1], el2no, np.real(ds), shading='flat', alpha=1.0, cmap=plt.cm.viridis) plt.colorbar()
def solve_eit(self, ex_mat=None, step=1, perm=None, parser=None, skip_jac=False): """ EIT simulation, generate perturbation matrix and forward v Parameters ---------- ex_mat: NDArray numLines x n_el array, stimulation matrix step: int the configuration of measurement electrodes (default: adjacent) perm: NDArray Mx1 array, initial x0. must be the same size with self.tri_perm parser: str if parser is 'fmmu', within each stimulation pattern, diff_pairs or boundary measurements are re-indexed and started from the positive stimulus electrode if parser is 'std', subtract_row start from the 1st electrode Returns ------- jac: NDArray number of measures x n_E complex array, the Jacobian v: NDArray number of measures x 1 array, simulated boundary measures b_matrix: NDArray back-projection mappings (smear matrix) """ # initialize/extract the scan lines (default: apposition) if ex_mat is None: ex_mat = eit_scan_lines(16, 8) # initialize the permittivity on element if perm is None: perm0 = self.tri_perm elif np.isscalar(perm): perm0 = np.ones(self.n_tri, dtype=np.float) else: assert perm.shape == (self.n_tri, ) perm0 = perm # calculate f and Jacobian iteratively over all stimulation lines jac, v, b_matrix = [], [], [] n_lines = ex_mat.shape[0] for i in range(n_lines): # FEM solver of one stimulation pattern, a row in ex_mat ex_line = ex_mat[i] f, jac_i = self.solve(ex_line, perm0, skip_jac) f_el = f[self.el_pos] # boundary measurements, subtract_row-voltages on electrodes diff_op = voltage_meter(ex_line, n_el=self.ne, step=step, parser=parser) v_diff = subtract_row(f_el, diff_op) if not skip_jac: jac_diff = subtract_row(jac_i, diff_op) # build bp projection matrix # 1. we can either smear at the center of elements, using # >> fe = np.mean(f[self.tri], axis=1) # 2. or, simply smear at the nodes using f b = smear(f, f_el, diff_op) # append v.append(v_diff) if not skip_jac: jac.append(jac_diff) b_matrix.append(b) # update output, now you can call p.jac, p.v, p.b_matrix pde_result = namedtuple("pde_result", ['jac', 'v', 'b_matrix']) p = pde_result(jac=np.vstack(jac) if jac else jac, v=np.hstack(v), b_matrix=np.vstack(b_matrix)) return p