Module dem_to_pf
@author: Alexandre Sac–Morane alexandre.sac-morane@uclouvain.be
This is the file used to transmit data between dem and phase field.
Expand source code
# -*- encoding=utf-8 -*-
import pickle, math, os, shutil
from pathlib import Path
from scipy.ndimage import binary_dilation, label
import numpy as np
import matplotlib.pyplot as plt
# own
from tools import *
from pf_to_dem import *
# -----------------------------------------------------------------------------#
def move_phasefield(dict_user, dict_sample):
'''
Move phase field maps by interpolation.
'''
# g2 (as g1 is fixed)
# load data
with open('data/dem_to_main.data', 'rb') as handle:
dict_save = pickle.load(handle)
displacement = dict_save['displacement']
# tracker
dict_user['L_displacement'].append(dict_save['displacement'][1])
# loading old variables
eta_1_map = dict_sample['eta_1_map']
# updating phase map
print('Updating phase field maps')
eta_1_map_new = np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x']))
# iteration on y
for i_y in range(len(dict_sample['y_L'])):
y = dict_sample['y_L'][i_y]
i_y_old = 0
# eta 1
if displacement[1] < 0:
if y-displacement[1] <= dict_sample['y_L'][-1]:
# look for window
while not (dict_sample['y_L'][i_y_old] <= y-displacement[1] and y-displacement[1] < dict_sample['y_L'][i_y_old+1]):
i_y_old = i_y_old + 1
# interpolate
eta_1_map_new[-1-i_y, :] = (eta_1_map[-1-(i_y_old+1), :] - eta_1_map[-1-i_y_old, :])/(dict_sample['y_L'][i_y_old+1] - dict_sample['y_L'][i_y_old])*\
(y-displacement[1] - dict_sample['y_L'][i_y_old]) + eta_1_map[-1-i_y_old, :]
elif displacement[1] > 0:
if dict_sample['y_L'][0] <= y-displacement[1]:
# look for window
while not (dict_sample['y_L'][i_y_old] <= y-displacement[1] and y-displacement[1] < dict_sample['y_L'][i_y_old+1]):
i_y_old = i_y_old + 1
# interpolate
eta_1_map_new[-1-i_y, :] = (eta_1_map[-1-(i_y_old+1), :] - eta_1_map[-1-i_y_old, :])/(dict_sample['y_L'][i_y_old+1] - dict_sample['y_L'][i_y_old])*\
(y-displacement[1] - dict_sample['y_L'][i_y_old]) + eta_1_map[-1-i_y_old, :]
else :
eta_1_map_new = eta_1_map
# The solute map is updated
# the solute is push out/in of the grain
# this is done in compute_kc() from dem_to_pf.py called later
# update variables
dict_sample['eta_1_map'] = eta_1_map_new
# write txts for phase field
if not dict_user['remesh']:
write_eta_txt(dict_user, dict_sample) # phase field
# -----------------------------------------------------------------------------#
def compute_as(dict_user, dict_sample):
'''
Compute activity of solid.
'''
# load data from dem
with open('data/dem_to_main.data', 'rb') as handle:
dict_save = pickle.load(handle)
contactPoint = dict_save['contact_point']
normalForce = dict_user['force_applied_target']
normalForce = normalForce/(1/(dict_user['n_dist']*dict_user['n_time']**2)) # normalization
contact_area = 1*(dict_sample['box_contact_x_max'] - dict_sample['box_contact_x_min'])
# tracker
dict_user['L_P_applied'].append(np.linalg.norm(normalForce)/contact_area)
# plot
if 'contact_pressure' in dict_user['L_figures'] :
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
# overlap
ax1.plot(dict_user['L_P_applied'])
ax1.set_title('Pressure at the contact (Pa)',fontsize=20)
fig.tight_layout()
fig.savefig('plot/contact_pressure.png')
plt.close(fig)
# init
dict_sample['as_map'] = np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x']))
# iterate on mesh
for i_x in range(len(dict_sample['x_L'])):
for i_y in range(len(dict_sample['y_L'])):
# determine pressure
if dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0: # in the contact
P = np.linalg.norm(normalForce)/contact_area # Pa
else : # not in the contact
P = 0 # Pa
# save in the map
dict_sample['as_map'][-1-i_y, i_x] = math.exp(P*dict_user['V_m']/(dict_user['R_cst']*dict_user['temperature']))
# write as
write_as_txt(dict_user, dict_sample)
# -----------------------------------------------------------------------------#
def compute_ed(dict_user, dict_sample):
'''
Compute the average ed in the sample, in the contact zone, in the large contact zone and track ed value at the center of the contact.
'''
# constants
k_diss = dict_user['k_diss']
k_prec = dict_user['k_prec']
c_eq = dict_user['C_eq']
# compute the map of ed
ed_map = np.zeros((len(dict_sample['y_L']), len(dict_sample['x_L'])))
# compute mean ed in contact
m_ed_contact = 0
n_contact = 0
m_ed_plus_contact = 0
n_plus_contact = 0
m_ed_minus_contact = 0
n_minus_contact = 0
m_ed_large_contact = 0
n_large_contact = 0
m_ed_plus_large_contact = 0
n_plus_large_contact = 0
m_ed_minus_large_contact = 0
n_minus_large_contact = 0
# iterate on mesh
for i_x in range(len(dict_sample['x_L'])):
for i_y in range(len(dict_sample['y_L'])):
# read variables
as_value = dict_sample['as_map'][-1-i_y, i_x]
c = dict_sample['c_map'][-1-i_y, i_x]
# compute and build map
if c < c_eq*as_value:
ed_value = k_diss*as_value*(1-c/(c_eq*as_value))
else :
ed_value = k_prec*as_value*(1-c/(c_eq*as_value))
ed_map[-1-i_y, i_x] = ed_value
# compute mean ed in contact
if dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0:
m_ed_contact = m_ed_contact + ed_value
n_contact = n_contact + 1
if ed_value > 0 :
m_ed_plus_contact = m_ed_plus_contact + ed_value
n_plus_contact = n_plus_contact + 1
else :
m_ed_minus_contact = m_ed_minus_contact + ed_value
n_minus_contact = n_minus_contact + 1
# compute mean ed in large contact
if dict_sample['eta_1_map'][-1-i_y, i_x] > 0.05 and dict_sample['y_L'][i_y] <= 0:
m_ed_large_contact = m_ed_large_contact + ed_value
n_large_contact = n_large_contact + 1
if ed_value > 0 :
m_ed_plus_large_contact = m_ed_plus_large_contact + ed_value
n_plus_large_contact = n_plus_large_contact + 1
else :
m_ed_minus_large_contact = m_ed_minus_large_contact + ed_value
n_minus_large_contact = n_minus_large_contact + 1
# tracker
dict_user['L_m_ed'].append(np.mean(ed_map))
add_element_list(dict_user['L_m_ed_contact'], m_ed_contact, n_contact)
add_element_list(dict_user['L_m_ed_large_contact'], m_ed_large_contact, n_large_contact)
add_element_list(dict_user['L_m_ed_plus_contact'], m_ed_plus_contact, n_plus_contact)
add_element_list(dict_user['L_m_ed_minus_contact'], m_ed_minus_contact, n_minus_contact)
add_element_list(dict_user['L_m_ed_plus_large_contact'], m_ed_plus_large_contact, n_plus_large_contact)
add_element_list(dict_user['L_m_ed_minus_large_contact'], m_ed_minus_large_contact, n_minus_large_contact)
# plot
if 'm_ed' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_m_ed'])
ax1.set_title('Mean tilting factor (-)',fontsize=20)
fig.tight_layout()
fig.savefig('plot/m_ed.png')
plt.close(fig)
# plot
if 'contact_distrib_m_ed' in dict_user['L_figures']:
fig, (ax1, ax2) = plt.subplots(1,2,figsize=(16,9))
# mean
ax1.plot(dict_user['L_m_ed_contact'], label='Contact')
ax1.plot(dict_user['L_m_ed_large_contact'], label= 'Large contact')
ax1.legend()
ax1.set_title('Mean (-)',fontsize=20)
# distribution
ax2.plot(dict_user['L_m_ed_plus_contact'], label='+ Contact')
ax2.plot(dict_user['L_m_ed_minus_contact'], label='- Contact')
ax2.plot(dict_user['L_m_ed_plus_large_contact'], label= '+ Large contact')
ax2.plot(dict_user['L_m_ed_minus_large_contact'], label= '- Large contact')
ax2.legend()
ax2.set_title('Mean of + and - (-)')
# close
plt.suptitle('Mean tilting factor in contact (-)',fontsize=20)
fig.tight_layout()
fig.savefig('plot/contact_distrib_m_ed.png')
plt.close(fig)
# find nearest node to contact point
with open('data/dem_to_main.data', 'rb') as handle:
dict_save = pickle.load(handle)
contactPoint = dict_save['contact_point']
L_search = list(abs(np.array(dict_sample['x_L']-contactPoint[0])))
i_x = L_search.index(min(L_search))
L_search = list(abs(np.array(dict_sample['y_L']-contactPoint[1])))
i_y = L_search.index(min(L_search))
# tracker
dict_user['L_ed_contact_point'].append(ed_map[-1-i_y, i_x])
# plot
if 'contact_point_ed' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_ed_contact_point'])
ax1.set_title('Tilting factor at contact point (-)',fontsize=20)
fig.tight_layout()
fig.savefig('plot/contact_point_ed.png')
plt.close(fig)
# compute saturation along the x axis at the contact point
L_profile_sat = []
L_x = []
# iterate on mesh
for i_x in range(len(dict_sample['x_L'])):
# read data
as_value = dict_sample['as_map'][-1-i_y, i_x]
c = dict_sample['c_map'][-1-i_y, i_x]
# compute saturation
if as_value*c_eq != c_eq:
saturation = 100*(c-c_eq)/(as_value*c_eq-c_eq)
# same profile
L_profile_sat.append(saturation)
L_x.append(dict_sample['x_L'][i_x])
# save
dict_user['L_L_profile_sat'].append(L_profile_sat)
dict_user['L_L_x'].append(L_x)
# compute solute concentration in pore
# and mean saturation in the contact
m_c_pore = 0
n_c_pore = 0
m_sat_contact = 0
n_sat_contact = 0
for i_x in range(len(dict_sample['x_L'])):
for i_y in range(len(dict_sample['y_L'])):
# in contact
if dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0:
as_value = dict_sample['as_map'][-1-i_y, i_x]
c = dict_sample['c_map'][-1-i_y, i_x]
saturation = 100*(c-c_eq)/(as_value*c_eq-c_eq)
m_sat_contact = m_sat_contact + saturation
n_sat_contact = n_sat_contact + 1
# in pore
elif dict_sample['eta_1_map'][-1-i_y, i_x] < dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] > 0:
c = dict_sample['c_map'][-1-i_y, i_x]
m_c_pore = m_c_pore + c
n_c_pore = n_c_pore + 1
dict_user['L_m_c_pore'].append(m_c_pore/n_c_pore)
dict_user['L_m_sat_contact'].append(m_sat_contact/n_sat_contact)
# plot
if 'saturation' in dict_user['L_figures']:
# compute the plot frequence
if len(dict_user['L_L_profile_sat']) > 10:
f_plot = len(dict_user['L_L_profile_sat'])/10
else :
f_plot = 1
# plot index
i_plot = 0
# create figure
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
# iterate on the iteration
for i_profile in range(len(dict_user['L_L_profile_sat'])):
if i_profile >= f_plot*i_plot:
ax1.plot(dict_user['L_L_x'][i_profile], dict_user['L_L_profile_sat'][i_profile], label=str(i_plot))
i_plot = i_plot + 1
ax1.set_title('saturation profile along the contact abscisse (%)',fontsize=20)
ax1.set_xlabel('x coordinate/ n_distance (-)')
ax1.legend()
fig.tight_layout()
fig.savefig('plot/saturation.png')
plt.close(fig)
# plot mean value
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_m_sat_contact'])
ax1.set_title('mean saturation in the contact (%)',fontsize=20)
ax1.set_xlabel('iteration (-)')
fig.tight_layout()
fig.savefig('plot/m_saturation.png')
plt.close(fig)
# plot
if 'm_c_pore' in dict_user['L_figures']:
# create figure
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_m_c_pore'])
ax1.set_title('solute concentration in pore space / n_concentration (-)',fontsize=20)
ax1.set_xlabel('iteration (-)')
ax1.legend()
fig.tight_layout()
fig.savefig('plot/solute_concentration_pore.png')
plt.close(fig)
# -----------------------------------------------------------------------------#
def add_element_list(data_list, data_sum, data_n):
'''
Add element to a list with condition.
if data_n != 0, add data_sum/data_n
else, add 0
'''
if data_n != 0:
data_list.append(data_sum/data_n)
else :
data_list.append(0)
# -----------------------------------------------------------------------------#
def compute_dt_PF_Aitken(dict_user, dict_sample):
'''
Compute the time step used in PF simulation with a method inspired by Aitken.
Several threshold values are used.
'''
# level 0
if abs(dict_user['L_m_ed_contact'][-1]) < dict_user['Aitken_1']:
dict_user['dt_PF'] = dict_user['dt_PF_0']
# level 1
if dict_user['Aitken_1'] <= abs(dict_user['L_m_ed_contact'][-1]) and abs(dict_user['L_m_ed_contact'][-1]) < dict_user['Aitken_2']:
dict_user['dt_PF'] = dict_user['dt_PF_1']
# level 2
if dict_user['Aitken_2'] <= abs(dict_user['L_m_ed_contact'][-1]) :
dict_user['dt_PF'] = dict_user['dt_PF_2']
# save and plot
dict_user['L_dt_PF'].append(dict_user['dt_PF'])
if 'dt_PF' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_dt_PF'])
ax1.set_yticks([dict_user['dt_PF_0'], dict_user['dt_PF_1'], dict_user['dt_PF_2']])
ax1.set_yticklabels(['Level 0', 'Level 1', 'Level 2'])
ax1.set_title('Time step used for PF (s)',fontsize=20)
fig.tight_layout()
fig.savefig('plot/dt_PF.png')
plt.close(fig)
#-------------------------------------------------------------------------------
def write_eta_txt(dict_user, dict_sample):
'''
Write a .txt file needed for MOOSE simulation.
This .txt file represent the phase field maps.
'''
file_to_write_1 = open('data/eta_1.txt','w')
# x
file_to_write_1.write('AXIS X\n')
line = ''
for x in dict_sample['x_L']:
line = line + str(x)+ ' '
line = line + '\n'
file_to_write_1.write(line)
# y
file_to_write_1.write('AXIS Y\n')
line = ''
for y in dict_sample['y_L']:
line = line + str(y)+ ' '
line = line + '\n'
file_to_write_1.write(line)
# data
file_to_write_1.write('DATA\n')
for j in range(len(dict_sample['y_L'])):
for i in range(len(dict_sample['x_L'])):
# grain
file_to_write_1.write(str(dict_sample['eta_1_map'][-1-j,i])+'\n')
# close
file_to_write_1.close()
#-------------------------------------------------------------------------------
def write_c_txt(dict_user, dict_sample):
'''
Write a .txt file needed for MOOSE simulation.
This .txt represents the solute map.
'''
file_to_write = open('data/c.txt','w')
# x
file_to_write.write('AXIS X\n')
line = ''
for x in dict_sample['x_L']:
line = line + str(x)+ ' '
line = line + '\n'
file_to_write.write(line)
# y
file_to_write.write('AXIS Y\n')
line = ''
for y in dict_sample['y_L']:
line = line + str(y)+ ' '
line = line + '\n'
file_to_write.write(line)
# data
file_to_write.write('DATA\n')
for j in range(len(dict_sample['y_L'])):
for i in range(len(dict_sample['x_L'])):
file_to_write.write(str(dict_sample['c_map'][-1-j,i])+'\n')
# close
file_to_write.close()
#-------------------------------------------------------------------------------
def write_as_txt(dict_user, dict_sample):
'''
Write a .txt file needed for MOOSE simulation.
This .txt represents the map of the solid activity.
'''
file_to_write = open('data/as.txt','w')
# x
file_to_write.write('AXIS X\n')
line = ''
for x in dict_sample['x_L']:
line = line + str(x)+ ' '
line = line + '\n'
file_to_write.write(line)
# y
file_to_write.write('AXIS Y\n')
line = ''
for y in dict_sample['y_L']:
line = line + str(y)+ ' '
line = line + '\n'
file_to_write.write(line)
# data
file_to_write.write('DATA\n')
for j in range(len(dict_sample['y_L'])):
for i in range(len(dict_sample['x_L'])):
file_to_write.write(str(dict_sample['as_map'][-1-j,i])+'\n')
# close
file_to_write.close()
#-------------------------------------------------------------------------------
def compute_kc(dict_user, dict_sample):
'''
Compute the diffusion coefficient of the solute.
Then write a .txt file needed for MOOSE simulation.
This .txt file represent the diffusion coefficient map.
'''
# loading old variable
c_map = dict_sample['c_map']
# updating solute map
c_map_new = c_map.copy()
# compute
kc_map = np.array(np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])), dtype = bool)
kc_pore_map = np.array(np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])), dtype = bool)
# iterate on x and y
for i_y in range(len(dict_sample['y_L'])):
for i_x in range(len(dict_sample['x_L'])):
if dict_sample['eta_1_map'][-1-i_y, i_x] < dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] > 0: # out of the grain
kc_map[-1-i_y, i_x] = True
kc_pore_map[-1-i_y, i_x] = True
elif dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0: # in the contact
kc_map[-1-i_y, i_x] = True
kc_pore_map[-1-i_y, i_x] = False
else :
kc_map[-1-i_y, i_x] = False
kc_pore_map[-1-i_y, i_x] = False
# dilation
dilated_M = binary_dilation(kc_map, dict_user['struct_element'])
#compute the map of the solute diffusion coefficient
kc_map = dict_user['D_solute']*dilated_M + 99*dict_user['D_solute']*kc_pore_map
# write
file_to_write_1 = open('data/kc.txt','w')
# x
file_to_write_1.write('AXIS X\n')
line = ''
for x in dict_sample['x_L']:
line = line + str(x)+ ' '
line = line + '\n'
file_to_write_1.write(line)
# y
file_to_write_1.write('AXIS Y\n')
line = ''
for y in dict_sample['y_L']:
line = line + str(y)+ ' '
line = line + '\n'
file_to_write_1.write(line)
# data
file_to_write_1.write('DATA\n')
for j in range(len(dict_sample['y_L'])):
for i in range(len(dict_sample['x_L'])):
# grain 1
file_to_write_1.write(str(kc_map[-1-j,i])+'\n')
# close
file_to_write_1.close()
# compute the number of grain detected in kc_map
invert_dilated_M = np.invert(dilated_M)
labelled_image, num_features = label(invert_dilated_M)
dict_user['L_grain_kc_map'].append(num_features)
# plot
if 'n_grain_kc_map' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_grain_kc_map'])
ax1.set_title('Number of grains detected (-)',fontsize=20)
fig.tight_layout()
fig.savefig('plot/n_grain_detected.png')
plt.close(fig)
# iterate on the mesh
for i_y in range(len(dict_sample['y_L'])):
for i_x in range(len(dict_sample['x_L'])):
# push solute out of the solid
if not dilated_M[i_y, i_x] and c_map[i_y, i_x] > dict_user['C_eq']: # threshold value
solute_moved = False
size_window = 1
# compute solute to move
solute_to_move = c_map[i_y, i_x] - dict_user['C_eq']
while not solute_moved :
i_window = 0
while not solute_moved and i_window <= size_window:
n_node_available = 0
#Look to move horizontaly and vertically
if i_window == 0 :
top_available = False
down_available = False
left_available = False
right_available = False
#to the top
if i_y - size_window > 0:
top_available = dilated_M[i_y-size_window, i_x]
if dilated_M[i_y-size_window, i_x] :
n_node_available = n_node_available + 1
#to the down
if i_y + size_window < len(dict_sample['y_L']):
down_available = dilated_M[i_y+size_window, i_x]
if dilated_M[i_y+size_window, i_x] :
n_node_available = n_node_available + 1
#to the left
if i_x - size_window > 0:
left_available = dilated_M[i_y, i_x-size_window]
if dilated_M[i_y, i_x-size_window] :
n_node_available = n_node_available + 1
#to the right
if i_x + size_window < len(dict_sample['x_L']):
right_available = dilated_M[i_y, i_x+size_window]
if dilated_M[i_y, i_x+size_window] :
n_node_available = n_node_available + 1
#move solute if et least one node is available
if n_node_available != 0 :
#to the top
if top_available:
c_map_new[i_y-size_window, i_x] = c_map_new[i_y-size_window, i_x] + solute_to_move/n_node_available
#to the down
if down_available:
c_map_new[i_y+size_window, i_x] = c_map_new[i_y+size_window, i_x] + solute_to_move/n_node_available
#to the left
if left_available:
c_map_new[i_y, i_x-size_window] = c_map_new[i_y, i_x-size_window] + solute_to_move/n_node_available
#to the right
if right_available:
c_map_new[i_y, i_x+size_window] = c_map_new[i_y, i_x+size_window] + solute_to_move/n_node_available
c_map_new[i_y, i_x] = dict_user['C_eq']
solute_moved = True
#Look to move diagonally
else :
top_min_available = False
top_max_available = False
down_min_available = False
down_max_available = False
left_min_available = False
left_max_available = False
right_min_available = False
right_max_available = False
#to the top
if i_y - size_window > 0:
if i_x - i_window > 0 :
top_min_available = dilated_M[i_y-size_window, i_x-i_window]
if dilated_M[i_y-size_window, i_x-i_window] :
n_node_available = n_node_available + 1
if i_x + i_window < len(dict_sample['x_L']):
top_max_available = dilated_M[i_y-size_window, i_x+i_window]
if dilated_M[i_y-size_window, i_x+i_window] :
n_node_available = n_node_available + 1
#to the down
if i_y + size_window < len(dict_sample['y_L']):
if i_x - i_window > 0 :
down_min_available = dilated_M[i_y+size_window, i_x-i_window]
if dilated_M[i_y+size_window, i_x-i_window] :
n_node_available = n_node_available + 1
if i_x + i_window < len(dict_sample['x_L']):
down_max_available = dilated_M[i_y+size_window, i_x+i_window]
if dilated_M[i_y+size_window, i_x+i_window] :
n_node_available = n_node_available + 1
#to the left
if i_x - size_window > 0:
if i_y - i_window > 0 :
left_min_available = dilated_M[i_y-i_window, i_x-size_window]
if dilated_M[i_y-i_window, i_x-size_window] :
n_node_available = n_node_available + 1
if i_y + i_window < len(dict_sample['y_L']):
left_max_available = dilated_M[i_y+i_window, i_x-size_window]
if dilated_M[i_y+i_window, i_x-size_window] :
n_node_available = n_node_available + 1
#to the right
if i_x + size_window < len(dict_sample['x_L']):
if i_x - i_window > 0 :
right_min_available = dilated_M[i_y-i_window, i_x+size_window]
if dilated_M[i_y-i_window, i_x+size_window] :
n_node_available = n_node_available + 1
if i_y + i_window < len(dict_sample['y_L']):
right_max_available = dilated_M[i_y+i_window, i_x+size_window]
if dilated_M[i_y+i_window, i_x+size_window] :
n_node_available = n_node_available + 1
#move solute if et least one node is available
if n_node_available != 0 :
#to the top
if top_min_available:
c_map_new[i_y-size_window, i_x-i_window] = c_map_new[i_y-size_window, i_x-i_window] + solute_to_move/n_node_available
if top_max_available:
c_map_new[i_y-size_window, i_x+i_window] = c_map_new[i_y-size_window, i_x+i_window] + solute_to_move/n_node_available
#to the down
if down_min_available:
c_map_new[i_y+size_window, i_x-i_window] = c_map_new[i_y+size_window, i_x-i_window] + solute_to_move/n_node_available
if down_max_available:
c_map_new[i_y+size_window, i_x+i_window] = c_map_new[i_y+size_window, i_x+i_window] + solute_to_move/n_node_available
#to the left
if left_min_available:
c_map_new[i_y-i_window, i_x-size_window] = c_map_new[i_y-i_window, i_x-size_window] + solute_to_move/n_node_available
if left_max_available:
c_map_new[i_y+i_window, i_x-size_window] = c_map_new[i_y+i_window, i_x-size_window] + solute_to_move/n_node_available
#to the right
if right_min_available:
c_map_new[i_y-i_window, i_x+size_window] = c_map_new[i_y-i_window, i_x+size_window] + solute_to_move/n_node_available
if right_max_available:
c_map_new[i_y+i_window, i_x+size_window] = c_map_new[i_y+i_window, i_x+size_window] + solute_to_move/n_node_available
c_map_new[i_y, i_x] = dict_user['C_eq']
solute_moved = True
i_window = i_window + 1
size_window = size_window + 1
# push solute in of the solid
if not dilated_M[i_y, i_x] and c_map[i_y, i_x] < dict_user['C_eq']: # threshold value
solute_moved = False
size_window = 1
# compute solute to move
solute_to_move = dict_user['C_eq'] - c_map[i_y, i_x]
while not solute_moved :
i_window = 0
while not solute_moved and i_window <= size_window:
n_node_available = 0
#Look to move horizontaly and vertically
if i_window == 0 :
top_available = False
down_available = False
left_available = False
right_available = False
#to the top
if i_y - size_window > 0:
top_available = dilated_M[i_y-size_window, i_x]
if dilated_M[i_y-size_window, i_x] :
n_node_available = n_node_available + 1
#to the down
if i_y + size_window < len(dict_sample['y_L']):
down_available = dilated_M[i_y+size_window, i_x]
if dilated_M[i_y+size_window, i_x] :
n_node_available = n_node_available + 1
#to the left
if i_x - size_window > 0:
left_available = dilated_M[i_y, i_x-size_window]
if dilated_M[i_y, i_x-size_window] :
n_node_available = n_node_available + 1
#to the right
if i_x + size_window < len(dict_sample['x_L']):
right_available = dilated_M[i_y, i_x+size_window]
if dilated_M[i_y, i_x+size_window] :
n_node_available = n_node_available + 1
#move solute if et least one node is available
if n_node_available != 0 :
#to the top
if top_available:
c_map_new[i_y-size_window, i_x] = c_map_new[i_y-size_window, i_x] - solute_to_move/n_node_available
#to the down
if down_available:
c_map_new[i_y+size_window, i_x] = c_map_new[i_y+size_window, i_x] - solute_to_move/n_node_available
#to the left
if left_available:
c_map_new[i_y, i_x-size_window] = c_map_new[i_y, i_x-size_window] - solute_to_move/n_node_available
#to the right
if right_available:
c_map_new[i_y, i_x+size_window] = c_map_new[i_y, i_x+size_window] - solute_to_move/n_node_available
c_map_new[i_y, i_x] = dict_user['C_eq']
solute_moved = True
#Look to move diagonally
else :
top_min_available = False
top_max_available = False
down_min_available = False
down_max_available = False
left_min_available = False
left_max_available = False
right_min_available = False
right_max_available = False
#to the top
if i_y - size_window > 0:
if i_x - i_window > 0 :
top_min_available = dilated_M[i_y-size_window, i_x-i_window]
if dilated_M[i_y-size_window, i_x-i_window] :
n_node_available = n_node_available + 1
if i_x + i_window < len(dict_sample['x_L']):
top_max_available = dilated_M[i_y-size_window, i_x+i_window]
if dilated_M[i_y-size_window, i_x+i_window] :
n_node_available = n_node_available + 1
#to the down
if i_y + size_window < len(dict_sample['y_L']):
if i_x - i_window > 0 :
down_min_available = dilated_M[i_y+size_window, i_x-i_window]
if dilated_M[i_y+size_window, i_x-i_window] :
n_node_available = n_node_available + 1
if i_x + i_window < len(dict_sample['x_L']):
down_max_available = dilated_M[i_y+size_window, i_x+i_window]
if dilated_M[i_y+size_window, i_x+i_window] :
n_node_available = n_node_available + 1
#to the left
if i_x - size_window > 0:
if i_y - i_window > 0 :
left_min_available = dilated_M[i_y-i_window, i_x-size_window]
if dilated_M[i_y-i_window, i_x-size_window] :
n_node_available = n_node_available + 1
if i_y + i_window < len(dict_sample['y_L']):
left_max_available = dilated_M[i_y+i_window, i_x-size_window]
if dilated_M[i_y+i_window, i_x-size_window] :
n_node_available = n_node_available + 1
#to the right
if i_x + size_window < len(dict_sample['x_L']):
if i_x - i_window > 0 :
right_min_available = dilated_M[i_y-i_window, i_x+size_window]
if dilated_M[i_y-i_window, i_x+size_window] :
n_node_available = n_node_available + 1
if i_y + i_window < len(dict_sample['y_L']):
right_max_available = dilated_M[i_y+i_window, i_x+size_window]
if dilated_M[i_y+i_window, i_x+size_window] :
n_node_available = n_node_available + 1
#move solute if et least one node is available
if n_node_available != 0 :
#to the top
if top_min_available:
c_map_new[i_y-size_window, i_x-i_window] = c_map_new[i_y-size_window, i_x-i_window] - solute_to_move/n_node_available
if top_max_available:
c_map_new[i_y-size_window, i_x+i_window] = c_map_new[i_y-size_window, i_x+i_window] - solute_to_move/n_node_available
#to the down
if down_min_available:
c_map_new[i_y+size_window, i_x-i_window] = c_map_new[i_y+size_window, i_x-i_window] - solute_to_move/n_node_available
if down_max_available:
c_map_new[i_y+size_window, i_x+i_window] = c_map_new[i_y+size_window, i_x+i_window] - solute_to_move/n_node_available
#to the left
if left_min_available:
c_map_new[i_y-i_window, i_x-size_window] = c_map_new[i_y-i_window, i_x-size_window] - solute_to_move/n_node_available
if left_max_available:
c_map_new[i_y+i_window, i_x-size_window] = c_map_new[i_y+i_window, i_x-size_window] - solute_to_move/n_node_available
#to the right
if right_min_available:
c_map_new[i_y-i_window, i_x+size_window] = c_map_new[i_y-i_window, i_x+size_window] - solute_to_move/n_node_available
if right_max_available:
c_map_new[i_y+i_window, i_x+size_window] = c_map_new[i_y+i_window, i_x+size_window] - solute_to_move/n_node_available
c_map_new[i_y, i_x] = dict_user['C_eq']
solute_moved = True
i_window = i_window + 1
size_window = size_window + 1
# save data
dict_sample['c_map'] = c_map_new
# write txt for the solute concentration map
write_c_txt(dict_user, dict_sample) # solute
#-------------------------------------------------------------------------------
def write_i(dict_user, dict_sample):
'''
Create the .i file to run MOOSE simulation.
The file is generated from a template nammed PF_ACS_base.i
'''
file_to_write = open('pf.i','w')
file_to_read = open('pf_base.i','r')
lines = file_to_read.readlines()
file_to_read.close()
j = 0
for line in lines :
j = j + 1
if j == 4:
line = line[:-1] + ' ' + str(len(dict_sample['x_L'])-1)+'\n'
elif j == 5:
line = line[:-1] + ' ' + str(len(dict_sample['y_L'])-1)+'\n'
elif j == 6:
line = line[:-1] + ' ' + str(min(dict_sample['x_L']))+'\n'
elif j == 7:
line = line[:-1] + ' ' + str(max(dict_sample['x_L']))+'\n'
elif j == 8:
line = line[:-1] + ' ' + str(min(dict_sample['y_L']))+'\n'
elif j == 9:
line = line[:-1] + ' ' + str(max(dict_sample['y_L']))+'\n'
elif j == 65:
line = line[:-1] + ' ' + str(1/dict_user['V_m'])+'\n'
elif j == 79:
line = line[:-1] + "'"+str(dict_user['Mobility_eff'])+' '+str(dict_user['kappa_eta'])+" 1'\n"
elif j == 101:
line = line[:-1] + ' ' + str(dict_user['Energy_barrier'])+"'\n"
elif j == 114:
line = line[:-1] + "'" + str(dict_user['C_eq']) + ' ' + str(dict_user['k_diss']) + ' ' + str(dict_user['k_prec']) + "'\n"
elif j == 171 or j == 172 or j == 174 or j == 175:
line = line[:-1] + ' ' + str(dict_user['crit_res']) +'\n'
elif j == 178:
line = line[:-1] + ' ' + str(dict_user['dt_PF']*dict_user['n_t_PF']) +'\n'
elif j == 182:
line = line[:-1] + ' ' + str(dict_user['dt_PF']) +'\n'
file_to_write.write(line)
file_to_write.close()
# -----------------------------------------------------------------------------#
def sort_files_yade():
'''
Sort vtk files from yade simulation.
'''
# look for the next indice
j = 0
filepath = Path('vtk/2grains_'+str(j)+'.vtk')
while filepath.exists():
j = j + 1
filepath = Path('vtk/2grains_'+str(j)+'.vtk')
# rename
os.rename('vtk/2grains-polyhedra-00000000.vtk','vtk/2grains_'+str(j)+'.vtk')
os.rename('vtk/grain_1-polyhedra-00000000.vtk','vtk/grain1_'+str(j)+'.vtk')
os.rename('vtk/grain_2-polyhedra-00000000.vtk','vtk/grain2_'+str(j)+'.vtk')
os.rename('vtk/2grains-polyhedra-00000001.vtk','vtk/2grains_'+str(j+1)+'.vtk')
os.rename('vtk/grain_1-polyhedra-00000001.vtk','vtk/grain1_'+str(j+1)+'.vtk')
os.rename('vtk/grain_2-polyhedra-00000001.vtk','vtk/grain2_'+str(j+1)+'.vtk')
# -----------------------------------------------------------------------------#
def compare_volumes(dict_user, dict_sample):
'''
Compare the volume of the contact in Moose and in Yade.
'''
# Yade
# already done in run_yade() in main.py
# Moose
# count
counter = 0
for i_y in range(len(dict_sample['y_L'])):
for i_x in range(len(dict_sample['x_L'])):
if dict_sample['eta_1_map'][-1-i_y, i_x] > 0.5 and dict_sample['y_L'][i_y] < 0:
counter = counter + 1
# adapt
contact_volume_moose = counter * 1*(dict_sample['x_L'][1]-dict_sample['x_L'][0])*(dict_sample['y_L'][1]-dict_sample['y_L'][0])
# tracker
dict_user['L_contact_volume_moose'].append(contact_volume_moose)
# plot
if 'contact_volume' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_contact_volume_yade'], label='Yade')
ax1.plot(dict_user['L_contact_volume_box'], label='Box')
ax1.plot(dict_user['L_contact_volume_moose'], label='Moose')
ax1.legend()
ax1.set_title(r'Contact volume ($m^3$)',fontsize = 30)
fig.tight_layout()
fig.savefig('plot/contact_volumes.png')
plt.close(fig)
# convert in nb of node
L_nb_mesh_contact = []
for i in range(len(dict_user['L_contact_volume_moose'])):
L_nb_mesh_contact.append(dict_user['L_contact_volume_moose'][i]/(1*(dict_sample['x_L'][1]-dict_sample['x_L'][0])*(dict_sample['y_L'][1]-dict_sample['y_L'][0])))
# plot
if 'contact_nb_node' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(L_nb_mesh_contact)
ax1.set_title(r'Number of node in contact volume (-)',fontsize = 30)
fig.tight_layout()
fig.savefig('plot/contact_nb_node.png')
plt.close(fig)
# -----------------------------------------------------------------------------#
def compute_contact_volume(dict_user, dict_sample):
'''
Characterize the contact volume.
'''
# build a polyhedra of the contact volume
L_vertices = interpolate_vertices_contact(dict_sample['eta_1_map'], dict_user, dict_sample)
# adapt for plot and search box sizes
L_vertices_x = []
L_vertices_y = []
min_set = False # bool for the first iteration
for v in L_vertices:
L_vertices_x.append(v[0])
L_vertices_y.append(v[1])
# set min, max values with the first vertex
if not min_set :
min_x = v[0]
max_x = v[0]
min_y = v[1]
max_y = v[1]
min_set = True
# compare to find extremum
else :
if v[0] < min_x:
min_x = v[0]
if max_x < v[0]:
max_x = v[0]
if v[1] < min_y:
min_y = v[1]
if max_y < v[1]:
max_y = v[1]
L_vertices_x.append(L_vertices_x[0])
L_vertices_y.append(L_vertices_y[0])
# save box contact
dict_sample['box_contact_x_min'] = min_x
dict_sample['box_contact_x_max'] = max_x
dict_sample['box_contact_y_min'] = min_y
dict_sample['box_contact_y_max'] = max_y
# capturing the grains boundaries
L_vertices_1 = interpolate_vertices(dict_sample['eta_1_map'], dict_sample['pos_1'], dict_user, dict_sample) # from pf_to_dem.py
# plot
if 'contact_detection' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
# g1
L_x, L_y = tuplet_to_list_no_centerized(L_vertices_1) # from tools.py
ax1.plot(L_x, L_y, label='G1')
# contact
#ax1.plot(L_vertices_x, L_vertices_y, 'x', label='Contact')
# box contact
ax1.plot([min_x, max_x, max_x, min_x, min_x], [min_y, min_y, max_y, max_y, min_y], label='Contact Box')
# close
ax1.legend()
ax1.axis('equal')
plt.suptitle('Contact Detection', fontsize=20)
fig.tight_layout()
if dict_user['print_all_contact_detection']:
fig.savefig('plot/contact_detection/'+str(dict_sample['i_DEMPF_ite'])+'.png')
else:
fig.savefig('plot/contact_detection.png')
plt.close(fig)
# compare contact volume in Moose and in Yade
compare_volumes(dict_user, dict_sample) # in dem_to_pf.py
# -----------------------------------------------------------------------------#
def interpolate_vertices_contact(eta_1_map, dict_user, dict_sample):
'''
Interpolate vertices for a contact between two polyhedrons.
'''
L_vertices = []
for i_x in range(len(dict_sample['x_L'])-1):
for i_y in range(len(dict_sample['y_L'])-1):
L_in_1 = [] # list the nodes inside the grain 1
if eta_1_map[-1-i_y , i_x] > dict_user['eta_contact_box_detection'] :
L_in_1.append(0)
if eta_1_map[-1-(i_y+1), i_x] > dict_user['eta_contact_box_detection'] :
L_in_1.append(1)
if eta_1_map[-1-(i_y+1), i_x+1] > dict_user['eta_contact_box_detection'] :
L_in_1.append(2)
if eta_1_map[-1-i_y , i_x+1] > dict_user['eta_contact_box_detection'] :
L_in_1.append(3)
if (L_in_1 != [] and L_in_1 != [0,1,2,3]) and ((dict_sample['y_L'][i_y]+dict_sample['y_L'][i_y+1])/2 < 0):
# iterate on the lines of the mesh to find the plane intersection for grain 1
L_p_1 = []
if (0 in L_in_1 and 1 not in L_in_1) or (0 not in L_in_1 and 1 in L_in_1):# line 01
x_p = dict_sample['x_L'][i_x]
y_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-i_y, i_x])/(eta_1_map[-1-(i_y+1), i_x]-eta_1_map[-1-i_y, i_x])*(dict_sample['y_L'][i_y+1]-dict_sample['y_L'][i_y])+dict_sample['y_L'][i_y]
L_p_1.append(np.array([x_p, y_p]))
if (1 in L_in_1 and 2 not in L_in_1) or (1 not in L_in_1 and 2 in L_in_1):# line 12
x_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-(i_y+1), i_x])/(eta_1_map[-1-(i_y+1), i_x+1]-eta_1_map[-1-(i_y+1), i_x])*(dict_sample['x_L'][i_x+1]-dict_sample['x_L'][i_x])+dict_sample['x_L'][i_x]
y_p = dict_sample['y_L'][i_y+1]
L_p_1.append(np.array([x_p, y_p]))
if (2 in L_in_1 and 3 not in L_in_1) or (2 not in L_in_1 and 3 in L_in_1):# line 23
x_p = dict_sample['x_L'][i_x+1]
y_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-i_y, i_x+1])/(eta_1_map[-1-(i_y+1), i_x+1]-eta_1_map[-1-i_y, i_x+1])*(dict_sample['y_L'][i_y+1]-dict_sample['y_L'][i_y])+dict_sample['y_L'][i_y]
L_p_1.append(np.array([x_p, y_p]))
if (3 in L_in_1 and 0 not in L_in_1) or (3 not in L_in_1 and 0 in L_in_1):# line 30
x_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-i_y, i_x])/(eta_1_map[-1-i_y, i_x+1]-eta_1_map[-1-i_y, i_x])*(dict_sample['x_L'][i_x+1]-dict_sample['x_L'][i_x])+dict_sample['x_L'][i_x]
y_p = dict_sample['y_L'][i_y]
L_p_1.append(np.array([x_p, y_p]))
# compute the mean point
p_mean_1 = np.array([0,0])
for p in L_p_1 :
p_mean_1 = p_mean_1 + p
p_mean_1 = p_mean_1/len(L_p_1)
L_vertices.append(p_mean_1)
return L_vertices
Functions
def move_phasefield()
-
Move phase field maps by interpolation.
Expand source code
def move_phasefield(dict_user, dict_sample): ''' Move phase field maps by interpolation. ''' # g2 (as g1 is fixed) # load data with open('data/dem_to_main.data', 'rb') as handle: dict_save = pickle.load(handle) displacement = dict_save['displacement'] # tracker dict_user['L_displacement'].append(dict_save['displacement'][1]) # loading old variables eta_1_map = dict_sample['eta_1_map'] # updating phase map print('Updating phase field maps') eta_1_map_new = np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])) # iteration on y for i_y in range(len(dict_sample['y_L'])): y = dict_sample['y_L'][i_y] i_y_old = 0 # eta 1 if displacement[1] < 0: if y-displacement[1] <= dict_sample['y_L'][-1]: # look for window while not (dict_sample['y_L'][i_y_old] <= y-displacement[1] and y-displacement[1] < dict_sample['y_L'][i_y_old+1]): i_y_old = i_y_old + 1 # interpolate eta_1_map_new[-1-i_y, :] = (eta_1_map[-1-(i_y_old+1), :] - eta_1_map[-1-i_y_old, :])/(dict_sample['y_L'][i_y_old+1] - dict_sample['y_L'][i_y_old])*\ (y-displacement[1] - dict_sample['y_L'][i_y_old]) + eta_1_map[-1-i_y_old, :] elif displacement[1] > 0: if dict_sample['y_L'][0] <= y-displacement[1]: # look for window while not (dict_sample['y_L'][i_y_old] <= y-displacement[1] and y-displacement[1] < dict_sample['y_L'][i_y_old+1]): i_y_old = i_y_old + 1 # interpolate eta_1_map_new[-1-i_y, :] = (eta_1_map[-1-(i_y_old+1), :] - eta_1_map[-1-i_y_old, :])/(dict_sample['y_L'][i_y_old+1] - dict_sample['y_L'][i_y_old])*\ (y-displacement[1] - dict_sample['y_L'][i_y_old]) + eta_1_map[-1-i_y_old, :] else : eta_1_map_new = eta_1_map # The solute map is updated # the solute is push out/in of the grain # this is done in compute_kc() from dem_to_pf.py called later # update variables dict_sample['eta_1_map'] = eta_1_map_new # write txts for phase field if not dict_user['remesh']: write_eta_txt(dict_user, dict_sample) # phase field
def compute_as()
-
Compute activity of solid.
Expand source code
def compute_as(dict_user, dict_sample): ''' Compute activity of solid. ''' # load data from dem with open('data/dem_to_main.data', 'rb') as handle: dict_save = pickle.load(handle) contactPoint = dict_save['contact_point'] normalForce = dict_user['force_applied_target'] normalForce = normalForce/(1/(dict_user['n_dist']*dict_user['n_time']**2)) # normalization contact_area = 1*(dict_sample['box_contact_x_max'] - dict_sample['box_contact_x_min']) # tracker dict_user['L_P_applied'].append(np.linalg.norm(normalForce)/contact_area) # plot if 'contact_pressure' in dict_user['L_figures'] : fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) # overlap ax1.plot(dict_user['L_P_applied']) ax1.set_title('Pressure at the contact (Pa)',fontsize=20) fig.tight_layout() fig.savefig('plot/contact_pressure.png') plt.close(fig) # init dict_sample['as_map'] = np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])) # iterate on mesh for i_x in range(len(dict_sample['x_L'])): for i_y in range(len(dict_sample['y_L'])): # determine pressure if dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0: # in the contact P = np.linalg.norm(normalForce)/contact_area # Pa else : # not in the contact P = 0 # Pa # save in the map dict_sample['as_map'][-1-i_y, i_x] = math.exp(P*dict_user['V_m']/(dict_user['R_cst']*dict_user['temperature'])) # write as write_as_txt(dict_user, dict_sample)
def compute_ed()
-
Compute the average ed in the sample, in the contact zone, in the large contact zone and track ed value at the center of the contact.
Expand source code
def compute_ed(dict_user, dict_sample): ''' Compute the average ed in the sample, in the contact zone, in the large contact zone and track ed value at the center of the contact. ''' # constants k_diss = dict_user['k_diss'] k_prec = dict_user['k_prec'] c_eq = dict_user['C_eq'] # compute the map of ed ed_map = np.zeros((len(dict_sample['y_L']), len(dict_sample['x_L']))) # compute mean ed in contact m_ed_contact = 0 n_contact = 0 m_ed_plus_contact = 0 n_plus_contact = 0 m_ed_minus_contact = 0 n_minus_contact = 0 m_ed_large_contact = 0 n_large_contact = 0 m_ed_plus_large_contact = 0 n_plus_large_contact = 0 m_ed_minus_large_contact = 0 n_minus_large_contact = 0 # iterate on mesh for i_x in range(len(dict_sample['x_L'])): for i_y in range(len(dict_sample['y_L'])): # read variables as_value = dict_sample['as_map'][-1-i_y, i_x] c = dict_sample['c_map'][-1-i_y, i_x] # compute and build map if c < c_eq*as_value: ed_value = k_diss*as_value*(1-c/(c_eq*as_value)) else : ed_value = k_prec*as_value*(1-c/(c_eq*as_value)) ed_map[-1-i_y, i_x] = ed_value # compute mean ed in contact if dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0: m_ed_contact = m_ed_contact + ed_value n_contact = n_contact + 1 if ed_value > 0 : m_ed_plus_contact = m_ed_plus_contact + ed_value n_plus_contact = n_plus_contact + 1 else : m_ed_minus_contact = m_ed_minus_contact + ed_value n_minus_contact = n_minus_contact + 1 # compute mean ed in large contact if dict_sample['eta_1_map'][-1-i_y, i_x] > 0.05 and dict_sample['y_L'][i_y] <= 0: m_ed_large_contact = m_ed_large_contact + ed_value n_large_contact = n_large_contact + 1 if ed_value > 0 : m_ed_plus_large_contact = m_ed_plus_large_contact + ed_value n_plus_large_contact = n_plus_large_contact + 1 else : m_ed_minus_large_contact = m_ed_minus_large_contact + ed_value n_minus_large_contact = n_minus_large_contact + 1 # tracker dict_user['L_m_ed'].append(np.mean(ed_map)) add_element_list(dict_user['L_m_ed_contact'], m_ed_contact, n_contact) add_element_list(dict_user['L_m_ed_large_contact'], m_ed_large_contact, n_large_contact) add_element_list(dict_user['L_m_ed_plus_contact'], m_ed_plus_contact, n_plus_contact) add_element_list(dict_user['L_m_ed_minus_contact'], m_ed_minus_contact, n_minus_contact) add_element_list(dict_user['L_m_ed_plus_large_contact'], m_ed_plus_large_contact, n_plus_large_contact) add_element_list(dict_user['L_m_ed_minus_large_contact'], m_ed_minus_large_contact, n_minus_large_contact) # plot if 'm_ed' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_m_ed']) ax1.set_title('Mean tilting factor (-)',fontsize=20) fig.tight_layout() fig.savefig('plot/m_ed.png') plt.close(fig) # plot if 'contact_distrib_m_ed' in dict_user['L_figures']: fig, (ax1, ax2) = plt.subplots(1,2,figsize=(16,9)) # mean ax1.plot(dict_user['L_m_ed_contact'], label='Contact') ax1.plot(dict_user['L_m_ed_large_contact'], label= 'Large contact') ax1.legend() ax1.set_title('Mean (-)',fontsize=20) # distribution ax2.plot(dict_user['L_m_ed_plus_contact'], label='+ Contact') ax2.plot(dict_user['L_m_ed_minus_contact'], label='- Contact') ax2.plot(dict_user['L_m_ed_plus_large_contact'], label= '+ Large contact') ax2.plot(dict_user['L_m_ed_minus_large_contact'], label= '- Large contact') ax2.legend() ax2.set_title('Mean of + and - (-)') # close plt.suptitle('Mean tilting factor in contact (-)',fontsize=20) fig.tight_layout() fig.savefig('plot/contact_distrib_m_ed.png') plt.close(fig) # find nearest node to contact point with open('data/dem_to_main.data', 'rb') as handle: dict_save = pickle.load(handle) contactPoint = dict_save['contact_point'] L_search = list(abs(np.array(dict_sample['x_L']-contactPoint[0]))) i_x = L_search.index(min(L_search)) L_search = list(abs(np.array(dict_sample['y_L']-contactPoint[1]))) i_y = L_search.index(min(L_search)) # tracker dict_user['L_ed_contact_point'].append(ed_map[-1-i_y, i_x]) # plot if 'contact_point_ed' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_ed_contact_point']) ax1.set_title('Tilting factor at contact point (-)',fontsize=20) fig.tight_layout() fig.savefig('plot/contact_point_ed.png') plt.close(fig) # compute saturation along the x axis at the contact point L_profile_sat = [] L_x = [] # iterate on mesh for i_x in range(len(dict_sample['x_L'])): # read data as_value = dict_sample['as_map'][-1-i_y, i_x] c = dict_sample['c_map'][-1-i_y, i_x] # compute saturation if as_value*c_eq != c_eq: saturation = 100*(c-c_eq)/(as_value*c_eq-c_eq) # same profile L_profile_sat.append(saturation) L_x.append(dict_sample['x_L'][i_x]) # save dict_user['L_L_profile_sat'].append(L_profile_sat) dict_user['L_L_x'].append(L_x) # compute solute concentration in pore # and mean saturation in the contact m_c_pore = 0 n_c_pore = 0 m_sat_contact = 0 n_sat_contact = 0 for i_x in range(len(dict_sample['x_L'])): for i_y in range(len(dict_sample['y_L'])): # in contact if dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0: as_value = dict_sample['as_map'][-1-i_y, i_x] c = dict_sample['c_map'][-1-i_y, i_x] saturation = 100*(c-c_eq)/(as_value*c_eq-c_eq) m_sat_contact = m_sat_contact + saturation n_sat_contact = n_sat_contact + 1 # in pore elif dict_sample['eta_1_map'][-1-i_y, i_x] < dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] > 0: c = dict_sample['c_map'][-1-i_y, i_x] m_c_pore = m_c_pore + c n_c_pore = n_c_pore + 1 dict_user['L_m_c_pore'].append(m_c_pore/n_c_pore) dict_user['L_m_sat_contact'].append(m_sat_contact/n_sat_contact) # plot if 'saturation' in dict_user['L_figures']: # compute the plot frequence if len(dict_user['L_L_profile_sat']) > 10: f_plot = len(dict_user['L_L_profile_sat'])/10 else : f_plot = 1 # plot index i_plot = 0 # create figure fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) # iterate on the iteration for i_profile in range(len(dict_user['L_L_profile_sat'])): if i_profile >= f_plot*i_plot: ax1.plot(dict_user['L_L_x'][i_profile], dict_user['L_L_profile_sat'][i_profile], label=str(i_plot)) i_plot = i_plot + 1 ax1.set_title('saturation profile along the contact abscisse (%)',fontsize=20) ax1.set_xlabel('x coordinate/ n_distance (-)') ax1.legend() fig.tight_layout() fig.savefig('plot/saturation.png') plt.close(fig) # plot mean value fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_m_sat_contact']) ax1.set_title('mean saturation in the contact (%)',fontsize=20) ax1.set_xlabel('iteration (-)') fig.tight_layout() fig.savefig('plot/m_saturation.png') plt.close(fig) # plot if 'm_c_pore' in dict_user['L_figures']: # create figure fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_m_c_pore']) ax1.set_title('solute concentration in pore space / n_concentration (-)',fontsize=20) ax1.set_xlabel('iteration (-)') ax1.legend() fig.tight_layout() fig.savefig('plot/solute_concentration_pore.png') plt.close(fig)
def add_element_list()
-
Add element to a list with condition.
if data_n != 0, add data_sum/data_n else, add 0.
Expand source code
def add_element_list(data_list, data_sum, data_n): ''' Add element to a list with condition. if data_n != 0, add data_sum/data_n else, add 0 ''' if data_n != 0: data_list.append(data_sum/data_n) else : data_list.append(0)
def compute_dt_PF_Aitken()
-
Compute the time step used in PF simulation with a method inspired by Aitken.
Several threshold values are used.
Expand source code
def compute_dt_PF_Aitken(dict_user, dict_sample): ''' Compute the time step used in PF simulation with a method inspired by Aitken. Several threshold values are used. ''' # level 0 if abs(dict_user['L_m_ed_contact'][-1]) < dict_user['Aitken_1']: dict_user['dt_PF'] = dict_user['dt_PF_0'] # level 1 if dict_user['Aitken_1'] <= abs(dict_user['L_m_ed_contact'][-1]) and abs(dict_user['L_m_ed_contact'][-1]) < dict_user['Aitken_2']: dict_user['dt_PF'] = dict_user['dt_PF_1'] # level 2 if dict_user['Aitken_2'] <= abs(dict_user['L_m_ed_contact'][-1]) : dict_user['dt_PF'] = dict_user['dt_PF_2'] # save and plot dict_user['L_dt_PF'].append(dict_user['dt_PF']) if 'dt_PF' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_dt_PF']) ax1.set_yticks([dict_user['dt_PF_0'], dict_user['dt_PF_1'], dict_user['dt_PF_2']]) ax1.set_yticklabels(['Level 0', 'Level 1', 'Level 2']) ax1.set_title('Time step used for PF (s)',fontsize=20) fig.tight_layout() fig.savefig('plot/dt_PF.png') plt.close(fig)
def write_eta_txt()
-
Write a .txt file needed for MOOSE simulation.
This .txt file represent the phase field maps.
Expand source code
def write_eta_txt(dict_user, dict_sample): ''' Write a .txt file needed for MOOSE simulation. This .txt file represent the phase field maps. ''' file_to_write_1 = open('data/eta_1.txt','w') # x file_to_write_1.write('AXIS X\n') line = '' for x in dict_sample['x_L']: line = line + str(x)+ ' ' line = line + '\n' file_to_write_1.write(line) # y file_to_write_1.write('AXIS Y\n') line = '' for y in dict_sample['y_L']: line = line + str(y)+ ' ' line = line + '\n' file_to_write_1.write(line) # data file_to_write_1.write('DATA\n') for j in range(len(dict_sample['y_L'])): for i in range(len(dict_sample['x_L'])): # grain file_to_write_1.write(str(dict_sample['eta_1_map'][-1-j,i])+'\n') # close file_to_write_1.close()
def write_c_txt()
-
Write a .txt file needed for MOOSE simulation.
This .txt file represent the solute map.
Expand source code
def write_c_txt(dict_user, dict_sample): ''' Write a .txt file needed for MOOSE simulation. This .txt represents the solute map. ''' file_to_write = open('data/c.txt','w') # x file_to_write.write('AXIS X\n') line = '' for x in dict_sample['x_L']: line = line + str(x)+ ' ' line = line + '\n' file_to_write.write(line) # y file_to_write.write('AXIS Y\n') line = '' for y in dict_sample['y_L']: line = line + str(y)+ ' ' line = line + '\n' file_to_write.write(line) # data file_to_write.write('DATA\n') for j in range(len(dict_sample['y_L'])): for i in range(len(dict_sample['x_L'])): file_to_write.write(str(dict_sample['c_map'][-1-j,i])+'\n') # close file_to_write.close()
def write_as_txt()
-
Write a .txt file needed for MOOSE simulation.
This .txt file represent the map of the solid activity.
Expand source code
def write_as_txt(dict_user, dict_sample): ''' Write a .txt file needed for MOOSE simulation. This .txt represents the map of the solid activity. ''' file_to_write = open('data/as.txt','w') # x file_to_write.write('AXIS X\n') line = '' for x in dict_sample['x_L']: line = line + str(x)+ ' ' line = line + '\n' file_to_write.write(line) # y file_to_write.write('AXIS Y\n') line = '' for y in dict_sample['y_L']: line = line + str(y)+ ' ' line = line + '\n' file_to_write.write(line) # data file_to_write.write('DATA\n') for j in range(len(dict_sample['y_L'])): for i in range(len(dict_sample['x_L'])): file_to_write.write(str(dict_sample['as_map'][-1-j,i])+'\n') # close file_to_write.close()
def compute_kc()
-
Compute the diffusion coefficient of the solute.
Then write a .txt file needed for MOOSE simulation. This .txt file represent the diffusion coefficient map.
Expand source code
def compute_kc(dict_user, dict_sample): ''' Compute the diffusion coefficient of the solute. Then write a .txt file needed for MOOSE simulation. This .txt file represent the diffusion coefficient map. ''' # loading old variable c_map = dict_sample['c_map'] # updating solute map c_map_new = c_map.copy() # compute kc_map = np.array(np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])), dtype = bool) kc_pore_map = np.array(np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])), dtype = bool) # iterate on x and y for i_y in range(len(dict_sample['y_L'])): for i_x in range(len(dict_sample['x_L'])): if dict_sample['eta_1_map'][-1-i_y, i_x] < dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] > 0: # out of the grain kc_map[-1-i_y, i_x] = True kc_pore_map[-1-i_y, i_x] = True elif dict_sample['eta_1_map'][-1-i_y, i_x] > dict_user['eta_contact_box_detection'] and dict_sample['y_L'][i_y] <= 0: # in the contact kc_map[-1-i_y, i_x] = True kc_pore_map[-1-i_y, i_x] = False else : kc_map[-1-i_y, i_x] = False kc_pore_map[-1-i_y, i_x] = False # dilation dilated_M = binary_dilation(kc_map, dict_user['struct_element']) #compute the map of the solute diffusion coefficient kc_map = dict_user['D_solute']*dilated_M + 99*dict_user['D_solute']*kc_pore_map # write file_to_write_1 = open('data/kc.txt','w') # x file_to_write_1.write('AXIS X\n') line = '' for x in dict_sample['x_L']: line = line + str(x)+ ' ' line = line + '\n' file_to_write_1.write(line) # y file_to_write_1.write('AXIS Y\n') line = '' for y in dict_sample['y_L']: line = line + str(y)+ ' ' line = line + '\n' file_to_write_1.write(line) # data file_to_write_1.write('DATA\n') for j in range(len(dict_sample['y_L'])): for i in range(len(dict_sample['x_L'])): # grain 1 file_to_write_1.write(str(kc_map[-1-j,i])+'\n') # close file_to_write_1.close() # compute the number of grain detected in kc_map invert_dilated_M = np.invert(dilated_M) labelled_image, num_features = label(invert_dilated_M) dict_user['L_grain_kc_map'].append(num_features) # plot if 'n_grain_kc_map' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_grain_kc_map']) ax1.set_title('Number of grains detected (-)',fontsize=20) fig.tight_layout() fig.savefig('plot/n_grain_detected.png') plt.close(fig) # iterate on the mesh for i_y in range(len(dict_sample['y_L'])): for i_x in range(len(dict_sample['x_L'])): # push solute out of the solid if not dilated_M[i_y, i_x] and c_map[i_y, i_x] > dict_user['C_eq']: # threshold value solute_moved = False size_window = 1 # compute solute to move solute_to_move = c_map[i_y, i_x] - dict_user['C_eq'] while not solute_moved : i_window = 0 while not solute_moved and i_window <= size_window: n_node_available = 0 #Look to move horizontaly and vertically if i_window == 0 : top_available = False down_available = False left_available = False right_available = False #to the top if i_y - size_window > 0: top_available = dilated_M[i_y-size_window, i_x] if dilated_M[i_y-size_window, i_x] : n_node_available = n_node_available + 1 #to the down if i_y + size_window < len(dict_sample['y_L']): down_available = dilated_M[i_y+size_window, i_x] if dilated_M[i_y+size_window, i_x] : n_node_available = n_node_available + 1 #to the left if i_x - size_window > 0: left_available = dilated_M[i_y, i_x-size_window] if dilated_M[i_y, i_x-size_window] : n_node_available = n_node_available + 1 #to the right if i_x + size_window < len(dict_sample['x_L']): right_available = dilated_M[i_y, i_x+size_window] if dilated_M[i_y, i_x+size_window] : n_node_available = n_node_available + 1 #move solute if et least one node is available if n_node_available != 0 : #to the top if top_available: c_map_new[i_y-size_window, i_x] = c_map_new[i_y-size_window, i_x] + solute_to_move/n_node_available #to the down if down_available: c_map_new[i_y+size_window, i_x] = c_map_new[i_y+size_window, i_x] + solute_to_move/n_node_available #to the left if left_available: c_map_new[i_y, i_x-size_window] = c_map_new[i_y, i_x-size_window] + solute_to_move/n_node_available #to the right if right_available: c_map_new[i_y, i_x+size_window] = c_map_new[i_y, i_x+size_window] + solute_to_move/n_node_available c_map_new[i_y, i_x] = dict_user['C_eq'] solute_moved = True #Look to move diagonally else : top_min_available = False top_max_available = False down_min_available = False down_max_available = False left_min_available = False left_max_available = False right_min_available = False right_max_available = False #to the top if i_y - size_window > 0: if i_x - i_window > 0 : top_min_available = dilated_M[i_y-size_window, i_x-i_window] if dilated_M[i_y-size_window, i_x-i_window] : n_node_available = n_node_available + 1 if i_x + i_window < len(dict_sample['x_L']): top_max_available = dilated_M[i_y-size_window, i_x+i_window] if dilated_M[i_y-size_window, i_x+i_window] : n_node_available = n_node_available + 1 #to the down if i_y + size_window < len(dict_sample['y_L']): if i_x - i_window > 0 : down_min_available = dilated_M[i_y+size_window, i_x-i_window] if dilated_M[i_y+size_window, i_x-i_window] : n_node_available = n_node_available + 1 if i_x + i_window < len(dict_sample['x_L']): down_max_available = dilated_M[i_y+size_window, i_x+i_window] if dilated_M[i_y+size_window, i_x+i_window] : n_node_available = n_node_available + 1 #to the left if i_x - size_window > 0: if i_y - i_window > 0 : left_min_available = dilated_M[i_y-i_window, i_x-size_window] if dilated_M[i_y-i_window, i_x-size_window] : n_node_available = n_node_available + 1 if i_y + i_window < len(dict_sample['y_L']): left_max_available = dilated_M[i_y+i_window, i_x-size_window] if dilated_M[i_y+i_window, i_x-size_window] : n_node_available = n_node_available + 1 #to the right if i_x + size_window < len(dict_sample['x_L']): if i_x - i_window > 0 : right_min_available = dilated_M[i_y-i_window, i_x+size_window] if dilated_M[i_y-i_window, i_x+size_window] : n_node_available = n_node_available + 1 if i_y + i_window < len(dict_sample['y_L']): right_max_available = dilated_M[i_y+i_window, i_x+size_window] if dilated_M[i_y+i_window, i_x+size_window] : n_node_available = n_node_available + 1 #move solute if et least one node is available if n_node_available != 0 : #to the top if top_min_available: c_map_new[i_y-size_window, i_x-i_window] = c_map_new[i_y-size_window, i_x-i_window] + solute_to_move/n_node_available if top_max_available: c_map_new[i_y-size_window, i_x+i_window] = c_map_new[i_y-size_window, i_x+i_window] + solute_to_move/n_node_available #to the down if down_min_available: c_map_new[i_y+size_window, i_x-i_window] = c_map_new[i_y+size_window, i_x-i_window] + solute_to_move/n_node_available if down_max_available: c_map_new[i_y+size_window, i_x+i_window] = c_map_new[i_y+size_window, i_x+i_window] + solute_to_move/n_node_available #to the left if left_min_available: c_map_new[i_y-i_window, i_x-size_window] = c_map_new[i_y-i_window, i_x-size_window] + solute_to_move/n_node_available if left_max_available: c_map_new[i_y+i_window, i_x-size_window] = c_map_new[i_y+i_window, i_x-size_window] + solute_to_move/n_node_available #to the right if right_min_available: c_map_new[i_y-i_window, i_x+size_window] = c_map_new[i_y-i_window, i_x+size_window] + solute_to_move/n_node_available if right_max_available: c_map_new[i_y+i_window, i_x+size_window] = c_map_new[i_y+i_window, i_x+size_window] + solute_to_move/n_node_available c_map_new[i_y, i_x] = dict_user['C_eq'] solute_moved = True i_window = i_window + 1 size_window = size_window + 1 # push solute in of the solid if not dilated_M[i_y, i_x] and c_map[i_y, i_x] < dict_user['C_eq']: # threshold value solute_moved = False size_window = 1 # compute solute to move solute_to_move = dict_user['C_eq'] - c_map[i_y, i_x] while not solute_moved : i_window = 0 while not solute_moved and i_window <= size_window: n_node_available = 0 #Look to move horizontaly and vertically if i_window == 0 : top_available = False down_available = False left_available = False right_available = False #to the top if i_y - size_window > 0: top_available = dilated_M[i_y-size_window, i_x] if dilated_M[i_y-size_window, i_x] : n_node_available = n_node_available + 1 #to the down if i_y + size_window < len(dict_sample['y_L']): down_available = dilated_M[i_y+size_window, i_x] if dilated_M[i_y+size_window, i_x] : n_node_available = n_node_available + 1 #to the left if i_x - size_window > 0: left_available = dilated_M[i_y, i_x-size_window] if dilated_M[i_y, i_x-size_window] : n_node_available = n_node_available + 1 #to the right if i_x + size_window < len(dict_sample['x_L']): right_available = dilated_M[i_y, i_x+size_window] if dilated_M[i_y, i_x+size_window] : n_node_available = n_node_available + 1 #move solute if et least one node is available if n_node_available != 0 : #to the top if top_available: c_map_new[i_y-size_window, i_x] = c_map_new[i_y-size_window, i_x] - solute_to_move/n_node_available #to the down if down_available: c_map_new[i_y+size_window, i_x] = c_map_new[i_y+size_window, i_x] - solute_to_move/n_node_available #to the left if left_available: c_map_new[i_y, i_x-size_window] = c_map_new[i_y, i_x-size_window] - solute_to_move/n_node_available #to the right if right_available: c_map_new[i_y, i_x+size_window] = c_map_new[i_y, i_x+size_window] - solute_to_move/n_node_available c_map_new[i_y, i_x] = dict_user['C_eq'] solute_moved = True #Look to move diagonally else : top_min_available = False top_max_available = False down_min_available = False down_max_available = False left_min_available = False left_max_available = False right_min_available = False right_max_available = False #to the top if i_y - size_window > 0: if i_x - i_window > 0 : top_min_available = dilated_M[i_y-size_window, i_x-i_window] if dilated_M[i_y-size_window, i_x-i_window] : n_node_available = n_node_available + 1 if i_x + i_window < len(dict_sample['x_L']): top_max_available = dilated_M[i_y-size_window, i_x+i_window] if dilated_M[i_y-size_window, i_x+i_window] : n_node_available = n_node_available + 1 #to the down if i_y + size_window < len(dict_sample['y_L']): if i_x - i_window > 0 : down_min_available = dilated_M[i_y+size_window, i_x-i_window] if dilated_M[i_y+size_window, i_x-i_window] : n_node_available = n_node_available + 1 if i_x + i_window < len(dict_sample['x_L']): down_max_available = dilated_M[i_y+size_window, i_x+i_window] if dilated_M[i_y+size_window, i_x+i_window] : n_node_available = n_node_available + 1 #to the left if i_x - size_window > 0: if i_y - i_window > 0 : left_min_available = dilated_M[i_y-i_window, i_x-size_window] if dilated_M[i_y-i_window, i_x-size_window] : n_node_available = n_node_available + 1 if i_y + i_window < len(dict_sample['y_L']): left_max_available = dilated_M[i_y+i_window, i_x-size_window] if dilated_M[i_y+i_window, i_x-size_window] : n_node_available = n_node_available + 1 #to the right if i_x + size_window < len(dict_sample['x_L']): if i_x - i_window > 0 : right_min_available = dilated_M[i_y-i_window, i_x+size_window] if dilated_M[i_y-i_window, i_x+size_window] : n_node_available = n_node_available + 1 if i_y + i_window < len(dict_sample['y_L']): right_max_available = dilated_M[i_y+i_window, i_x+size_window] if dilated_M[i_y+i_window, i_x+size_window] : n_node_available = n_node_available + 1 #move solute if et least one node is available if n_node_available != 0 : #to the top if top_min_available: c_map_new[i_y-size_window, i_x-i_window] = c_map_new[i_y-size_window, i_x-i_window] - solute_to_move/n_node_available if top_max_available: c_map_new[i_y-size_window, i_x+i_window] = c_map_new[i_y-size_window, i_x+i_window] - solute_to_move/n_node_available #to the down if down_min_available: c_map_new[i_y+size_window, i_x-i_window] = c_map_new[i_y+size_window, i_x-i_window] - solute_to_move/n_node_available if down_max_available: c_map_new[i_y+size_window, i_x+i_window] = c_map_new[i_y+size_window, i_x+i_window] - solute_to_move/n_node_available #to the left if left_min_available: c_map_new[i_y-i_window, i_x-size_window] = c_map_new[i_y-i_window, i_x-size_window] - solute_to_move/n_node_available if left_max_available: c_map_new[i_y+i_window, i_x-size_window] = c_map_new[i_y+i_window, i_x-size_window] - solute_to_move/n_node_available #to the right if right_min_available: c_map_new[i_y-i_window, i_x+size_window] = c_map_new[i_y-i_window, i_x+size_window] - solute_to_move/n_node_available if right_max_available: c_map_new[i_y+i_window, i_x+size_window] = c_map_new[i_y+i_window, i_x+size_window] - solute_to_move/n_node_available c_map_new[i_y, i_x] = dict_user['C_eq'] solute_moved = True i_window = i_window + 1 size_window = size_window + 1 # save data dict_sample['c_map'] = c_map_new # write txt for the solute concentration map write_c_txt(dict_user, dict_sample) # solute
def write_i()
-
Create the .i file to run MOOSE simulation.
The file is generated from a template nammed PF_ACS_base.i
Expand source code
def write_i(dict_user, dict_sample): ''' Create the .i file to run MOOSE simulation. The file is generated from a template nammed PF_ACS_base.i ''' file_to_write = open('pf.i','w') file_to_read = open('pf_base.i','r') lines = file_to_read.readlines() file_to_read.close() j = 0 for line in lines : j = j + 1 if j == 4: line = line[:-1] + ' ' + str(len(dict_sample['x_L'])-1)+'\n' elif j == 5: line = line[:-1] + ' ' + str(len(dict_sample['y_L'])-1)+'\n' elif j == 6: line = line[:-1] + ' ' + str(min(dict_sample['x_L']))+'\n' elif j == 7: line = line[:-1] + ' ' + str(max(dict_sample['x_L']))+'\n' elif j == 8: line = line[:-1] + ' ' + str(min(dict_sample['y_L']))+'\n' elif j == 9: line = line[:-1] + ' ' + str(max(dict_sample['y_L']))+'\n' elif j == 65: line = line[:-1] + ' ' + str(1/dict_user['V_m'])+'\n' elif j == 79: line = line[:-1] + "'"+str(dict_user['Mobility_eff'])+' '+str(dict_user['kappa_eta'])+" 1'\n" elif j == 101: line = line[:-1] + ' ' + str(dict_user['Energy_barrier'])+"'\n" elif j == 114: line = line[:-1] + "'" + str(dict_user['C_eq']) + ' ' + str(dict_user['k_diss']) + ' ' + str(dict_user['k_prec']) + "'\n" elif j == 171 or j == 172 or j == 174 or j == 175: line = line[:-1] + ' ' + str(dict_user['crit_res']) +'\n' elif j == 178: line = line[:-1] + ' ' + str(dict_user['dt_PF']*dict_user['n_t_PF']) +'\n' elif j == 182: line = line[:-1] + ' ' + str(dict_user['dt_PF']) +'\n' file_to_write.write(line) file_to_write.close()
def sort_files_yade()
-
Sort vtk files from yade simulation.
Expand source code
def sort_files_yade(): ''' Sort vtk files from yade simulation. ''' # look for the next indice j = 0 filepath = Path('vtk/2grains_'+str(j)+'.vtk') while filepath.exists(): j = j + 1 filepath = Path('vtk/2grains_'+str(j)+'.vtk') # rename os.rename('vtk/2grains-polyhedra-00000000.vtk','vtk/2grains_'+str(j)+'.vtk') os.rename('vtk/grain_1-polyhedra-00000000.vtk','vtk/grain1_'+str(j)+'.vtk') os.rename('vtk/grain_2-polyhedra-00000000.vtk','vtk/grain2_'+str(j)+'.vtk') os.rename('vtk/2grains-polyhedra-00000001.vtk','vtk/2grains_'+str(j+1)+'.vtk') os.rename('vtk/grain_1-polyhedra-00000001.vtk','vtk/grain1_'+str(j+1)+'.vtk') os.rename('vtk/grain_2-polyhedra-00000001.vtk','vtk/grain2_'+str(j+1)+'.vtk')
def compare_volumes()
-
Compare the volume of the contact in Moose and in Yade.
Expand source code
def compare_volumes(dict_user, dict_sample): ''' Compare the volume of the contact in Moose and in Yade. ''' # Yade # already done in run_yade() in main.py # Moose # count counter = 0 for i_y in range(len(dict_sample['y_L'])): for i_x in range(len(dict_sample['x_L'])): if dict_sample['eta_1_map'][-1-i_y, i_x] > 0.5 and dict_sample['y_L'][i_y] < 0: counter = counter + 1 # adapt contact_volume_moose = counter * 1*(dict_sample['x_L'][1]-dict_sample['x_L'][0])*(dict_sample['y_L'][1]-dict_sample['y_L'][0]) # tracker dict_user['L_contact_volume_moose'].append(contact_volume_moose) # plot if 'contact_volume' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_contact_volume_yade'], label='Yade') ax1.plot(dict_user['L_contact_volume_box'], label='Box') ax1.plot(dict_user['L_contact_volume_moose'], label='Moose') ax1.legend() ax1.set_title(r'Contact volume ($m^3$)',fontsize = 30) fig.tight_layout() fig.savefig('plot/contact_volumes.png') plt.close(fig) # convert in nb of node L_nb_mesh_contact = [] for i in range(len(dict_user['L_contact_volume_moose'])): L_nb_mesh_contact.append(dict_user['L_contact_volume_moose'][i]/(1*(dict_sample['x_L'][1]-dict_sample['x_L'][0])*(dict_sample['y_L'][1]-dict_sample['y_L'][0]))) # plot if 'contact_nb_node' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(L_nb_mesh_contact) ax1.set_title(r'Number of node in contact volume (-)',fontsize = 30) fig.tight_layout() fig.savefig('plot/contact_nb_node.png') plt.close(fig)
def compute_contact_volume()
-
Characterize the contact volume.
Expand source code
def compute_contact_volume(dict_user, dict_sample): ''' Characterize the contact volume. ''' # build a polyhedra of the contact volume L_vertices = interpolate_vertices_contact(dict_sample['eta_1_map'], dict_user, dict_sample) # adapt for plot and search box sizes L_vertices_x = [] L_vertices_y = [] min_set = False # bool for the first iteration for v in L_vertices: L_vertices_x.append(v[0]) L_vertices_y.append(v[1]) # set min, max values with the first vertex if not min_set : min_x = v[0] max_x = v[0] min_y = v[1] max_y = v[1] min_set = True # compare to find extremum else : if v[0] < min_x: min_x = v[0] if max_x < v[0]: max_x = v[0] if v[1] < min_y: min_y = v[1] if max_y < v[1]: max_y = v[1] L_vertices_x.append(L_vertices_x[0]) L_vertices_y.append(L_vertices_y[0]) # save box contact dict_sample['box_contact_x_min'] = min_x dict_sample['box_contact_x_max'] = max_x dict_sample['box_contact_y_min'] = min_y dict_sample['box_contact_y_max'] = max_y # capturing the grains boundaries L_vertices_1 = interpolate_vertices(dict_sample['eta_1_map'], dict_sample['pos_1'], dict_user, dict_sample) # from pf_to_dem.py # plot if 'contact_detection' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) # g1 L_x, L_y = tuplet_to_list_no_centerized(L_vertices_1) # from tools.py ax1.plot(L_x, L_y, label='G1') # contact #ax1.plot(L_vertices_x, L_vertices_y, 'x', label='Contact') # box contact ax1.plot([min_x, max_x, max_x, min_x, min_x], [min_y, min_y, max_y, max_y, min_y], label='Contact Box') # close ax1.legend() ax1.axis('equal') plt.suptitle('Contact Detection', fontsize=20) fig.tight_layout() if dict_user['print_all_contact_detection']: fig.savefig('plot/contact_detection/'+str(dict_sample['i_DEMPF_ite'])+'.png') else: fig.savefig('plot/contact_detection.png') plt.close(fig) # compare contact volume in Moose and in Yade compare_volumes(dict_user, dict_sample) # in dem_to_pf.py
def interpolate_vertices_contact()
-
Interpolate vertices for a contact between two polyhedrons.
Expand source code
def interpolate_vertices_contact(eta_1_map, dict_user, dict_sample): ''' Interpolate vertices for a contact between two polyhedrons. ''' L_vertices = [] for i_x in range(len(dict_sample['x_L'])-1): for i_y in range(len(dict_sample['y_L'])-1): L_in_1 = [] # list the nodes inside the grain 1 if eta_1_map[-1-i_y , i_x] > dict_user['eta_contact_box_detection'] : L_in_1.append(0) if eta_1_map[-1-(i_y+1), i_x] > dict_user['eta_contact_box_detection'] : L_in_1.append(1) if eta_1_map[-1-(i_y+1), i_x+1] > dict_user['eta_contact_box_detection'] : L_in_1.append(2) if eta_1_map[-1-i_y , i_x+1] > dict_user['eta_contact_box_detection'] : L_in_1.append(3) if (L_in_1 != [] and L_in_1 != [0,1,2,3]) and ((dict_sample['y_L'][i_y]+dict_sample['y_L'][i_y+1])/2< 0): # iterate on the lines of the mesh to find the plane intersection for grain 1 L_p_1 = [] if (0 in L_in_1 and 1 not in L_in_1) or (0 not in L_in_1 and 1 in L_in_1):# line 01 x_p = dict_sample['x_L'][i_x] y_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-i_y, i_x])/(eta_1_map[-1-(i_y+1), i_x]-eta_1_map[-1-i_y, i_x])*(dict_sample['y_L'][i_y+1]-dict_sample['y_L'][i_y])+dict_sample['y_L'][i_y] L_p_1.append(np.array([x_p, y_p])) if (1 in L_in_1 and 2 not in L_in_1) or (1 not in L_in_1 and 2 in L_in_1):# line 12 x_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-(i_y+1), i_x])/(eta_1_map[-1-(i_y+1), i_x+1]-eta_1_map[-1-(i_y+1), i_x])*(dict_sample['x_L'][i_x+1]-dict_sample['x_L'][i_x])+dict_sample['x_L'][i_x] y_p = dict_sample['y_L'][i_y+1] L_p_1.append(np.array([x_p, y_p])) if (2 in L_in_1 and 3 not in L_in_1) or (2 not in L_in_1 and 3 in L_in_1):# line 23 x_p = dict_sample['x_L'][i_x+1] y_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-i_y, i_x+1])/(eta_1_map[-1-(i_y+1), i_x+1]-eta_1_map[-1-i_y, i_x+1])*(dict_sample['y_L'][i_y+1]-dict_sample['y_L'][i_y])+dict_sample['y_L'][i_y] L_p_1.append(np.array([x_p, y_p])) if (3 in L_in_1 and 0 not in L_in_1) or (3 not in L_in_1 and 0 in L_in_1):# line 30 x_p = (dict_user['eta_contact_box_detection']-eta_1_map[-1-i_y, i_x])/(eta_1_map[-1-i_y, i_x+1]-eta_1_map[-1-i_y, i_x])*(dict_sample['x_L'][i_x+1]-dict_sample['x_L'][i_x])+dict_sample['x_L'][i_x] y_p = dict_sample['y_L'][i_y] L_p_1.append(np.array([x_p, y_p])) # compute the mean point p_mean_1 = np.array([0,0]) for p in L_p_1 : p_mean_1 = p_mean_1 + p p_mean_1 = p_mean_1/len(L_p_1) L_vertices.append(p_mean_1) return L_vertices