#!/usr/bin/env python import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as mtick from tkinter import Tk from tkinter.filedialog import askopenfilename, asksaveasfile, askdirectory import pandas as pd import tkinter as tk from statistics import mean from scipy.signal import find_peaks import matplotlib.transforms as mtransforms def error_plot(folder,t_step,r_criteria,save): # Load iterations and residual error histor = folder + '/histor.dat' input = open(histor, 'r') output = open(folder + "/histor_better.dat", 'w') output.writelines(line.strip() +'\n' for line in input) input.close() output.close() error_info = pd.read_csv(folder + "/histor_better.dat", sep=' ', header=None, usecols=(0,1,2)) # Select only last iteration of residual error error=[] for n in range(1,error_info.shape[0]): if (error_info[0][n]>error_info[0][n-1]): error.append(error_info[2][n-1]) time = np.linspace(start = t_step, stop = len(error)*t_step, num = len(error)) # Plots of interest # Liniar Scale plt.figure() plt.plot(time,error) plt.plot(time,r_criteria*np.ones(len(error)),'r') plt.ylabel('Residual error') plt.xlabel('Time steps') plt.title('Last nonlinear residual error for each time step') plt.grid(True) if save: plt.savefig(plt_folder + case + '_Last_nonlin_res_error.pdf') # Semilog scale plt.figure() plt.semilogy(time,error) plt.semilogy(time,r_criteria*np.ones(len(error)),'r') plt.ylabel('Residual error') plt.xlabel('Time steps') plt.title('Log - Last nonlinear residual error for each time step') plt.grid(True) if save: plt.savefig(plt_folder + case + '_Log_Last_nonlin_res_error.pdf') def periodicity(project,folder,dt,T_cyc,n_cyc): pressure = np.loadtxt(folder+'/PHistRCR.dat',skiprows=2,) time = np.linspace(0,T_cyc*n_cyc,round(T_cyc/dt*n_cyc)) peak_P = [] peak_P_pos = [] Nc = round(T_cyc/dt) for i in range(0,n_cyc): peak_P.append(np.amax(pressure[i*Nc:Nc*(i+1),-1])/1333.22) peak_P_pos.append(np.where(pressure[i*Nc:Nc*(i+1),-1] == np.amax(pressure[i*Nc:Nc*(i+1),-1]))[0][0]+Nc*i) peak_Pdiff = [peak_P[n]-peak_P[n-1] for n in range(1,len(peak_P))] peak_Pdiff = list(map(abs, peak_Pdiff)) fig, ax = plt.subplots() ax.plot(time,pressure[:,-1]/1333.22) ax.plot(time[peak_P_pos], peak_P,'ro',label='Cylce pike') ax.set(xlabel='time [s]', ylabel='Pressure [mmHg]', title='Pressure @ last outlet') ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.legend(loc=0) plt.show() if (peak_Pdiff[-1]<=1): print('The numerical simulation \'{0}\' has achieve periodicity!\nSystolic Blood Pressure (SBP):\nsecond-last cycle = {1:.2f} mmHg,\nlast cycle = {2:.2f} mmHg,\n\u0394mmHg = {3:.2f} mmHg'.format(project,peak_P[-2],peak_P[-1],peak_Pdiff[-1])) def pressure(folder,N_ts,T_cyc,dt,n_cyc): pressure = np.loadtxt(folder+'/PHistRCR.dat',skiprows=2,) Nc = round(T_cyc/dt) time = np.linspace(0,T_cyc,Nc) fig, ax = plt.subplots() SBP = np.empty(pressure.shape[1]) DBP = np.empty(pressure.shape[1]) MBP = np.empty(pressure.shape[1]) for i in range(0,pressure.shape[1]): ax.plot(time,pressure[N_ts-Nc:N_ts,i]/1333.22,label='ROI-'+str(i+2)) SBP[i] = (np.amax(pressure[N_ts-Nc:N_ts,i]/1333.22)) DBP[i] = (np.amin(pressure[N_ts-Nc:N_ts,i]/1333.22)) MBP[i] = (mean(pressure[N_ts-Nc:N_ts,i]/1333.22)) PP = SBP-DBP ax.set(xlabel='time [s]', ylabel='Pressure [mmHg]', title='Pressure @ each outlet') ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.legend(loc=0) plt.show() return (DBP,MBP,SBP,PP) def flow(folder,N_ts,T_cyc,dt,n_cyc): flow = np.loadtxt(folder+'/QHistRCR.dat',skiprows=2,) Nc = round(T_cyc/dt) time = np.linspace(0,T_cyc,Nc) fig, ax = plt.subplots() Q = np.empty(flow.shape[1]) for i in range(0,flow.shape[1]): ax.plot(time,flow[N_ts-Nc:N_ts,i],label='ROI-'+str(i+2)) Q[i] = (mean(flow[N_ts-Nc:N_ts,i])) ax.set(xlabel='time [s]', ylabel='Flow [mL/s]', title='Flow @ each outlet') ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.legend(loc=0) plt.show() return Q def inlet_flow_waveform(project_folder,t_btw_rst,N_ts,dt,T_cyc,n_cyc): x = np.loadtxt(project_folder+'/ROI-1.flow') t = x[:,0] Q = -x[:,1] Nt_pts = np.linspace(t_btw_rst,N_ts,int(N_ts/t_btw_rst)) t_pts = Nt_pts*dt # Put all the time values on a single cardiac cylce for n in range(len(t_pts)): tmp=divmod(t_pts[n],T_cyc) t_pts[n]=tmp[1] if round(tmp[1],3) == 0: t_pts[n]=T_cyc # Interpolate the flow rate to obtain the location of the point Q_pts = np.interp(t_pts, t, Q) fig, ax = plt.subplots() ax.plot(t, Q, 'r') ax.plot(t_pts, Q_pts, 'ob') trans_offset = mtransforms.offset_copy(ax.transData, fig=fig, x=-0, y=0.15, units='inches') ax.set(xlabel='Time [s]', ylabel='Flow Rate - Q [mL/s]', title='Inlet Flow rate Waveform - 1 cycle') ax.set_ylim([-10, 90]) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # Adding label to the points time = ['$t_1$', '$t_2$', '$t_3$', '$t_4$', '$t_5$', '$t_6$'] for x, y, t in zip(t_pts[(-n_cyc-1):], Q_pts[(-n_cyc-1):], time): plt.text(x, y, t, transform=trans_offset, fontsize=12) plt.show()