Module IC
@author: Alexandre Sac–Morane alexandre.sac-morane@uclouvain.be
This is the file where the initial conditions are defined.
Expand source code
# -*- encoding=utf-8 -*-
from pathlib import Path
import numpy as np
import math, skfmm, pickle, os
# ------------------------------------------------------------------------------------------------------------------------------------------ #
def load_microstructure(dict_user, dict_sample):
'''
Load microstructure as initial conditions.
Mesh and phase field maps are generated
'''
# ------------------------------------------------------------------------------------------------------------------------------------------ #
# Load data and apply initial force
if not Path('ms/from_ic.data').exists():
# transmit data from main
dict_save = {
'Poisson': dict_user['Poisson'],
'E': dict_user['E'],
'kn': dict_user['kn_dem'],
'ks': dict_user['ks_dem'],
'force_applied': dict_user['force_applied']
}
with open('ms/from_main_to_ic.data', 'wb') as handle:
pickle.dump(dict_save, handle, protocol=pickle.HIGHEST_PROTOCOL)
# run simulation
os.system('yadedaily -j '+str(dict_user['n_proc'])+' -x -n dem_base_ic.py')
#os.system('yadedaily -j '+str(dict_user['n_proc'])+' dem_base_ic.py')
print('end of the initialization\n')
# ------------------------------------------------------------------------------------------------------------------------------------------ #
# Load data
with open('ms/from_ic.data', 'rb') as handle:
dict_save = pickle.load(handle)
# update dict
dict_user['extrude_z'] = dict_save['extrude_z']
dict_user['margins'] = dict_save['margins']
dict_sample['L_pos_w'] = []
for pos_w in dict_save['L_pos_w']:
dict_sample['L_pos_w'].append(pos_w*1e-6/dict_user['n_dist'])
# ------------------------------------------------------------------------------------------------------------------------------------------ #
# Compute mesh dependent data
# mesh size
dict_user['m_size'] = dict_save['m_size']*1e-6/dict_user['n_dist']
# phase-field interface width
dict_user['w_int'] = dict_user['m_size']*dict_user['n_int']
# phase-field gradient coefficient
dict_user['kappa_eta'] = dict_user['Energy_barrier']*dict_user['w_int']*dict_user['w_int']/9.86
# phase-field kinetics of dissolution/precipitation
dict_user['k_diss'] = dict_user['k_diss']*(0.005)/(dict_user['m_size']) # ed_j = ed_i*m_i/m_j
dict_user['k_prec'] = dict_user['k_prec']*(0.005)/(dict_user['m_size']) # ed_j = ed_i*m_i/m_j
# size fluid film
dict_user['size_film'] = dict_user['m_size']*dict_user['n_size_film']
# solute diffusion coefficient
dict_user['D_solute'] = dict_user['D_solute']/2/dict_user['size_film']
# ------------------------------------------------------------------------------------------------------------------------------------------ #
# Create initial mesh
print("Creating initial mesh")
# limits
x_L_min = dict_sample['L_pos_w'][0] -2*dict_user['w_int']
x_L_max = dict_sample['L_pos_w'][1] +2*dict_user['w_int']
y_L_min = dict_sample['L_pos_w'][2] -2*dict_user['w_int']
y_L_max = dict_sample['L_pos_w'][3] +2*dict_user['w_int']
# mesh
x_L = np.arange(x_L_min, x_L_max+dict_user['m_size']*0.1, dict_user['m_size'])
y_L = np.arange(y_L_min, y_L_max+dict_user['m_size']*0.1, dict_user['m_size'])
# ------------------------------------------------------------------------------------------------------------------------------------------ #
# Create Phase-Field
print("Creating initial phase field maps")
L_etai_map = []
# iterate on grain
for i_data in range(dict_save['n_grains']):
# load data
with open('ms/from_ic_grain_'+str(i_data)+'.data', 'rb') as handle:
dict_save = pickle.load(handle)
x_L_i = []
for x in dict_save['x_L']:
x_L_i.append(x*1e-6/dict_user['n_dist'])
y_L_i = []
for y in dict_save['y_L']:
y_L_i.append(y*1e-6/dict_user['n_dist'])
ls_map_i = dict_save['ls_map']
# Create binary map
bin_i_map = -np.ones((len(y_L), len(x_L)))
# iteration on x
for j_x in range(len(x_L_i)):
# iteration on y
for j_y in range(len(y_L_i)):
# find j (local) in i (global): nearest node
L_search = list(abs(np.array(x_L-x_L_i[j_x])))
i_x = L_search.index(min(L_search))
L_search = list(abs(np.array(y_L-y_L_i[j_y])))
i_y = L_search.index(min(L_search))
# compute the binary map
if ls_map_i[-1-j_y, j_x] < 0:
bin_i_map[-1-i_y, i_x] = 1
else:
bin_i_map[-1-i_y, i_x] = -1
# compute the signed distance function
sdf_i_map = -skfmm.distance(bin_i_map, dx=np.array([dict_user['m_size'], dict_user['m_size']]))
# compute phase variable
eta_i_map = np.zeros((len(y_L), len(x_L)))
# iteration on x
for i_x in range(len(x_L)):
# iteration on y
for i_y in range(len(y_L)):
sdf = sdf_i_map[-1-i_y, i_x]
# cosine profile
if sdf > dict_user['w_int']/2 :
eta_i_map[-1-i_y, i_x] = 0
elif sdf < -dict_user['w_int']/2 :
eta_i_map[-1-i_y, i_x] = 1
else :
eta_i_map[-1-i_y, i_x] = 0.5*(1+math.cos(math.pi*(sdf+dict_user['w_int']/2)/dict_user['w_int']))
# save
L_etai_map.append(eta_i_map)
# save dict
dict_sample['L_etai_map'] = L_etai_map
dict_sample['x_L'] = x_L
dict_sample['y_L'] = y_L
dict_user['n_mesh_x'] = len(x_L)
dict_user['n_mesh_y'] = len(y_L)
# ------------------------------------------------------------------------------------------------------------------------------------------ #
def create_solute(dict_user, dict_sample):
'''
Create the map of the solute distribution.
'''
c_map = np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x']))
for i_x in range(len(dict_sample['x_L'])):
for i_y in range(len(dict_sample['y_L'])):
c_map[-1-i_y, i_x] = dict_user['C_eq'] # system at the equilibrium initialy
# save in dict
dict_sample['c_map'] = c_map
Functions
def load_microstructure()
-
Load microstructure as initial conditions.
Mesh and phase field maps are generated.
Expand source code
def load_microstructure(dict_user, dict_sample): ''' Load microstructure as initial conditions. Mesh and phase field maps are generated ''' # ------------------------------------------------------------------------------------------------------------------------------------------ # # Load data and apply initial force if not Path('ms/from_ic.data').exists(): # transmit data from main dict_save = { 'Poisson': dict_user['Poisson'], 'E': dict_user['E'], 'kn': dict_user['kn_dem'], 'ks': dict_user['ks_dem'], 'force_applied': dict_user['force_applied'] } with open('ms/from_main_to_ic.data', 'wb') as handle: pickle.dump(dict_save, handle, protocol=pickle.HIGHEST_PROTOCOL) # run simulation os.system('yadedaily -j '+str(dict_user['n_proc'])+' -x -n dem_base_ic.py') #os.system('yadedaily -j '+str(dict_user['n_proc'])+' dem_base_ic.py') print('end of the initialization\n') # ------------------------------------------------------------------------------------------------------------------------------------------ # # Load data with open('ms/from_ic.data', 'rb') as handle: dict_save = pickle.load(handle) # update dict dict_user['extrude_z'] = dict_save['extrude_z'] dict_user['margins'] = dict_save['margins'] dict_sample['L_pos_w'] = [] for pos_w in dict_save['L_pos_w']: dict_sample['L_pos_w'].append(pos_w*1e-6/dict_user['n_dist']) # ------------------------------------------------------------------------------------------------------------------------------------------ # # Compute mesh dependent data # mesh size dict_user['m_size'] = dict_save['m_size']*1e-6/dict_user['n_dist'] # phase-field interface width dict_user['w_int'] = dict_user['m_size']*dict_user['n_int'] # phase-field gradient coefficient dict_user['kappa_eta'] = dict_user['Energy_barrier']*dict_user['w_int']*dict_user['w_int']/9.86 # phase-field kinetics of dissolution/precipitation dict_user['k_diss'] = dict_user['k_diss']*(0.005)/(dict_user['m_size']) # ed_j = ed_i*m_i/m_j dict_user['k_prec'] = dict_user['k_prec']*(0.005)/(dict_user['m_size']) # ed_j = ed_i*m_i/m_j # size fluid film dict_user['size_film'] = dict_user['m_size']*dict_user['n_size_film'] # solute diffusion coefficient dict_user['D_solute'] = dict_user['D_solute']/2/dict_user['size_film'] # ------------------------------------------------------------------------------------------------------------------------------------------ # # Create initial mesh print("Creating initial mesh") # limits x_L_min = dict_sample['L_pos_w'][0] -2*dict_user['w_int'] x_L_max = dict_sample['L_pos_w'][1] +2*dict_user['w_int'] y_L_min = dict_sample['L_pos_w'][2] -2*dict_user['w_int'] y_L_max = dict_sample['L_pos_w'][3] +2*dict_user['w_int'] # mesh x_L = np.arange(x_L_min, x_L_max+dict_user['m_size']*0.1, dict_user['m_size']) y_L = np.arange(y_L_min, y_L_max+dict_user['m_size']*0.1, dict_user['m_size']) # ------------------------------------------------------------------------------------------------------------------------------------------ # # Create Phase-Field print("Creating initial phase field maps") L_etai_map = [] # iterate on grain for i_data in range(dict_save['n_grains']): # load data with open('ms/from_ic_grain_'+str(i_data)+'.data', 'rb') as handle: dict_save = pickle.load(handle) x_L_i = [] for x in dict_save['x_L']: x_L_i.append(x*1e-6/dict_user['n_dist']) y_L_i = [] for y in dict_save['y_L']: y_L_i.append(y*1e-6/dict_user['n_dist']) ls_map_i = dict_save['ls_map'] # Create binary map bin_i_map = -np.ones((len(y_L), len(x_L))) # iteration on x for j_x in range(len(x_L_i)): # iteration on y for j_y in range(len(y_L_i)): # find j (local) in i (global): nearest node L_search = list(abs(np.array(x_L-x_L_i[j_x]))) i_x = L_search.index(min(L_search)) L_search = list(abs(np.array(y_L-y_L_i[j_y]))) i_y = L_search.index(min(L_search)) # compute the binary map if ls_map_i[-1-j_y, j_x] < 0: bin_i_map[-1-i_y, i_x] = 1 else: bin_i_map[-1-i_y, i_x] = -1 # compute the signed distance function sdf_i_map = -skfmm.distance(bin_i_map, dx=np.array([dict_user['m_size'], dict_user['m_size']])) # compute phase variable eta_i_map = np.zeros((len(y_L), len(x_L))) # iteration on x for i_x in range(len(x_L)): # iteration on y for i_y in range(len(y_L)): sdf = sdf_i_map[-1-i_y, i_x] # cosine profile if sdf > dict_user['w_int']/2 : eta_i_map[-1-i_y, i_x] = 0 elif sdf < -dict_user['w_int']/2 : eta_i_map[-1-i_y, i_x] = 1 else : eta_i_map[-1-i_y, i_x] = 0.5*(1+math.cos(math.pi*(sdf+dict_user['w_int']/2)/dict_user['w_int'])) # save L_etai_map.append(eta_i_map) # save dict dict_sample['L_etai_map'] = L_etai_map dict_sample['x_L'] = x_L dict_sample['y_L'] = y_L dict_user['n_mesh_x'] = len(x_L) dict_user['n_mesh_y'] = len(y_L)
def create_solute()
-
Create the map of the solute distribution.
Expand source code
def create_solute(dict_user, dict_sample): ''' Create the map of the solute distribution. ''' c_map = np.zeros((dict_user['n_mesh_y'], dict_user['n_mesh_x'])) for i_x in range(len(dict_sample['x_L'])): for i_y in range(len(dict_sample['y_L'])): c_map[-1-i_y, i_x] = dict_user['C_eq'] # system at the equilibrium initialy # save in dict dict_sample['c_map'] = c_map