Module pf_to_dem
@author: Alexandre Sac–Morane alexandre.sac-morane@uclouvain.be
This is the file used to transmit data between phase field and dem.
Expand source code
# -*- encoding=utf-8 -*-
import pickle, math, os, shutil
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
import vtk
from vtk.util.numpy_support import vtk_to_numpy
# own
import tools
# -----------------------------------------------------------------------------#
def index_to_str(j):
'''
Convert a integer into a string with the format XXX.
'''
if j < 10:
return '00'+str(j)
elif 10<=j and j < 100:
return '0'+str(j)
else :
return str(j)
# -----------------------------------------------------------------------------#
def read_vtk(dict_user, dict_sample, j_str):
'''
Read the last vtk files to obtain data from MOOSE.
Do not work calling yade.
'''
eta_1_map_old = dict_sample['eta_1_map'].copy()
c_map_old = dict_sample['c_map'].copy()
L_eta1 = []
L_c = []
if not dict_sample['Map_known']:
L_limits = []
L_XYZ = []
L_L_i_XYZ_used = []
else :
L_XYZ = dict_sample['L_XYZ']
# iterate on the proccessors used
for i_proc in range(dict_user['n_proc']):
# name of the file to load
namefile = 'vtk/pf_other_'+j_str+'_'+str(i_proc)+'.vtu'
# load a vtk file as input
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName(namefile)
reader.Update()
# Grab a scalar from the vtk file
nodes_vtk_array = reader.GetOutput().GetPoints().GetData()
eta1_vtk_array = reader.GetOutput().GetPointData().GetArray("eta1")
c_vtk_array = reader.GetOutput().GetPointData().GetArray("c")
#Get the coordinates of the nodes and the scalar values
nodes_array = vtk_to_numpy(nodes_vtk_array)
eta1_array = vtk_to_numpy(eta1_vtk_array)
c_array = vtk_to_numpy(c_vtk_array)
# map is not know
if not dict_sample['Map_known']:
# look for limits
x_min = None
x_max = None
y_min = None
y_max = None
# save the map
L_i_XYZ_used = []
# Must detect common zones between processors
for i_XYZ in range(len(nodes_array)) :
XYZ = nodes_array[i_XYZ]
# Do not consider twice a point
if list(XYZ) not in L_XYZ :
L_XYZ.append(list(XYZ))
L_eta1.append(eta1_array[i_XYZ])
L_c.append(c_array[i_XYZ])
L_i_XYZ_used.append(i_XYZ)
# set first point
if x_min == None :
x_min = list(XYZ)[0]
x_max = list(XYZ)[0]
y_min = list(XYZ)[1]
y_max = list(XYZ)[1]
# look for limits of the processor
else :
if list(XYZ)[0] < x_min:
x_min = list(XYZ)[0]
if list(XYZ)[0] > x_max:
x_max = list(XYZ)[0]
if list(XYZ)[1] < y_min:
y_min = list(XYZ)[1]
if list(XYZ)[1] > y_max:
y_max = list(XYZ)[1]
# Here the algorithm can be help as the mapping is known
L_L_i_XYZ_used.append(L_i_XYZ_used)
# save limits
L_limits.append([x_min,x_max,y_min,y_max])
# map is known
else :
# the last term considered is at the end of the list
if dict_sample['L_L_i_XYZ_used'][i_proc][-1] == len(nodes_array)-1:
L_eta1 = list(L_eta1) + list(eta1_array)
L_c = list(L_c) + list(c_array)
# the last term considered is not at the end of the list
else :
L_eta1 = list(L_eta1) + list(eta1_array[dict_sample['L_L_i_XYZ_used'][i_proc][0]: dict_sample['L_L_i_XYZ_used'][i_proc][-1]+1])
L_c = list(L_c) + list(c_array[dict_sample['L_L_i_XYZ_used'][i_proc][0]: dict_sample['L_L_i_XYZ_used'][i_proc][-1]+1])
if not dict_sample['Map_known']:
# plot processors distribution
if 'processor' in dict_user['L_figures'] and not dict_user['remesh']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
# parameters
title_fontsize = 20
for i_proc in range(len(L_limits)):
limits = L_limits[i_proc]
ax1.plot([limits[0],limits[1],limits[1],limits[0],limits[0]],[limits[2],limits[2],limits[3],limits[3],limits[2]], label='proc '+str(i_proc))
ax1.legend()
ax1.set_xlabel('X (m)')
ax1.set_ylabel('Y (m)')
ax1.set_title('Processor i has the priority on i+1',fontsize = title_fontsize)
fig.suptitle('Processors ditribution',fontsize = 1.2*title_fontsize)
fig.tight_layout()
fig.savefig('plot/processors_distribution.png')
plt.close(fig)
# the map is known
dict_sample['Map_known'] = True
dict_sample['L_L_i_XYZ_used'] = L_L_i_XYZ_used
dict_sample['L_XYZ'] = L_XYZ
# rebuild map from lists
for i_XYZ in range(len(L_XYZ)):
# find nearest node
L_search = list(abs(np.array(dict_sample['x_L']-L_XYZ[i_XYZ][0])))
i_x = L_search.index(min(L_search))
L_search = list(abs(np.array(dict_sample['y_L']-L_XYZ[i_XYZ][1])))
i_y = L_search.index(min(L_search))
# rewrite map
dict_sample['eta_1_map'][-1-i_y, i_x] = L_eta1[i_XYZ]
dict_sample['c_map'][-1-i_y, i_x] = L_c[i_XYZ]
# -----------------------------------------------------------------------------#
def compute_vertices(dict_user, dict_sample):
'''
From a phase map, compute vertices coordinates for polyhedral.
'''
# compute vertices for grain
L_vertices_1 = interpolate_vertices(dict_sample['eta_1_map'], dict_sample['pos_1'], dict_user, dict_sample)
# compute vertices for plate
L_vertices_2 = ((min(dict_sample['x_L']), 0, 0,),
(max(dict_sample['x_L']), 0, 0,),
(max(dict_sample['x_L']), min(dict_sample['y_L']), 0,),
(min(dict_sample['x_L']), min(dict_sample['y_L']), 0,),
(min(dict_sample['x_L']), 0, 1,),
(max(dict_sample['x_L']), 0, 1,),
(max(dict_sample['x_L']), min(dict_sample['y_L']), 1,),
(min(dict_sample['x_L']), min(dict_sample['y_L']), 1,))
# save data
dict_save = {
'L_vertices_1': L_vertices_1,
'L_vertices_2': L_vertices_2
}
with open('data/planes.data', 'wb') as handle:
pickle.dump(dict_save, handle, protocol=pickle.HIGHEST_PROTOCOL)
# compute sample height and vertical strain
L_x_1, L_y_1 = tools.tuplet_to_list(L_vertices_1) # from tools.py
sample_height = max(L_y_1)
dict_user['L_sample_height'].append(sample_height)
# compute sphericities
AreaSphericity, DiameterSphericity, CircleRatioSphericity, PerimeterSphericity, WidthToLengthRatioSpericity = tools.compute_sphericities(L_vertices_1) # from tools.py
# save and plot
dict_user['L_AreaSphericity'].append(AreaSphericity)
dict_user['L_DiameterSphericity'].append(DiameterSphericity)
dict_user['L_CircleRatioSphericity'].append(CircleRatioSphericity)
dict_user['L_PerimeterSphericity'].append(PerimeterSphericity)
dict_user['L_WidthToLengthRatioSpericity'].append(WidthToLengthRatioSpericity)
if 'sphericities' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_AreaSphericity'], label='Area sphericity')
ax1.plot(dict_user['L_DiameterSphericity'], label='Diameter sphericity')
ax1.plot(dict_user['L_CircleRatioSphericity'], label='Circle ratio sphericity')
ax1.plot(dict_user['L_PerimeterSphericity'], label='Perimeter sphericity')
ax1.plot(dict_user['L_WidthToLengthRatioSpericity'], label='Width/Length spericity')
ax1.legend()
plt.suptitle('Grain sphericities (G1)', fontsize=20)
fig.tight_layout()
fig.savefig('plot/sphericities.png')
plt.close(fig)
# -----------------------------------------------------------------------------#
def interpolate_vertices(eta_i_map, center, dict_user, dict_sample):
'''
Interpolate vertices for polyhedral.
'''
map_phi = []
L_phi = []
for i_phi in range(dict_user['n_phi']):
phi = 2*math.pi*i_phi/dict_user['n_phi']
L_phi.append(phi)
map_phi.append([])
L_phi.append(2*math.pi)
for i_x in range(len(dict_sample['x_L'])-1):
for i_y in range(len(dict_sample['y_L'])-1):
L_in = [] # list the nodes inside the grain
if eta_i_map[-1-i_y , i_x] > 0.5 :
L_in.append(0)
if eta_i_map[-1-(i_y+1), i_x] > 0.5 :
L_in.append(1)
if eta_i_map[-1-(i_y+1), i_x+1] > 0.5 :
L_in.append(2)
if eta_i_map[-1-i_y , i_x+1] > 0.5 :
L_in.append(3)
if L_in != [] and L_in != [0,1,2,3]:
center_mesh = (np.array([dict_sample['x_L'][i_x], dict_sample['y_L'][i_y]])+np.array([dict_sample['x_L'][i_x+1], dict_sample['y_L'][i_y+1]]))/2
u = (center_mesh-np.array(center))/np.linalg.norm(center_mesh-np.array(center))
# compute phi
if u[1]>=0:
phi = math.acos(u[0])
else :
phi = 2*math.pi-math.acos(u[0])
# iterate on the lines of the mesh to find the plane intersection
L_p = []
if (0 in L_in and 1 not in L_in) or (0 not in L_in and 1 in L_in):# line 01
x_p = dict_sample['x_L'][i_x]
y_p = (0.5-eta_i_map[-1-i_y, i_x])/(eta_i_map[-1-(i_y+1), i_x]-eta_i_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.append(np.array([x_p, y_p]))
if (1 in L_in and 2 not in L_in) or (1 not in L_in and 2 in L_in):# line 12
x_p = (0.5-eta_i_map[-1-(i_y+1), i_x])/(eta_i_map[-1-(i_y+1), i_x+1]-eta_i_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.append(np.array([x_p, y_p]))
if (2 in L_in and 3 not in L_in) or (2 not in L_in and 3 in L_in):# line 23
x_p = dict_sample['x_L'][i_x+1]
y_p = (0.5-eta_i_map[-1-i_y, i_x+1])/(eta_i_map[-1-(i_y+1), i_x+1]-eta_i_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.append(np.array([x_p, y_p]))
if (3 in L_in and 0 not in L_in) or (3 not in L_in and 0 in L_in):# line 30
x_p = (0.5-eta_i_map[-1-i_y, i_x])/(eta_i_map[-1-i_y, i_x+1]-eta_i_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.append(np.array([x_p, y_p]))
# compute the mean point
p_mean = np.array([0,0])
for p in L_p :
p_mean = p_mean + p
p_mean = p_mean/len(L_p)
# look phi in L_phi
i_phi = 0
while not (L_phi[i_phi] <= phi and phi <= L_phi[i_phi+1]) :
i_phi = i_phi + 1
# save p_mean in the map
map_phi[i_phi].append(p_mean)
L_vertices = ()
# interpolate plane (Least squares method)
for i_phi in range(len(map_phi)):
if map_phi[i_phi] != []:
# mean vertices
mean_v = np.array([0, 0])
for v_i in map_phi[i_phi]:
mean_v = mean_v + v_i/len(map_phi[i_phi])
# save
L_vertices = L_vertices + ((mean_v[0], mean_v[1], 0,),)
L_vertices = L_vertices + ((mean_v[0], mean_v[1], 1),)
return L_vertices
# -----------------------------------------------------------------------------#
def control_force(dict_user, dict_sample):
'''
Control force applied in DEM with the contact volume.
Because of the fact that convvex shape is not possible in Yade.
'''
# determine the volume contact in Moose (etai ad j > 0.5)
V_contact_moose = 0
for i_x in range(len(dict_sample['x_L'])):
for i_y in range(len(dict_sample['y_L'])):
if dict_sample['eta_1_map'][-1-i_y, i_x] > 0.5 and dict_sample['y_L'][i_y]<=0:
V_contact_moose = V_contact_moose + (dict_sample['x_L'][1]-dict_sample['x_L'][0])*(dict_sample['y_L'][1]-dict_sample['y_L'][0])*1
# compare with the volume contact expected
# in Yade, F=k*V and 1/k = 1/Y1 + 1/Y2
V_expected = 2*dict_user['force_applied_target']/dict_user['E']
# the comparison is important if multiple controls are done per one PFDEM iteration
# if only only control is done, the adaptation of the force can be done always
#if V_contact_moose < (1-dict_user['steady_state_detection'])*V_expected or (1+dict_user['steady_state_detection'])*V_expected < V_contact_moose:
if True:
# control the force applied
dict_user['force_applied'] = dict_user['force_applied']*V_expected/V_contact_moose
# save and plot
dict_user['L_force_applied'].append(dict_user['force_applied'])
if 'force_applied' in dict_user['L_figures']:
fig, (ax1) = plt.subplots(1,1,figsize=(16,9))
ax1.plot(dict_user['L_force_applied'])
plt.suptitle('Force applied in Yade (DEM)', fontsize=20)
fig.tight_layout()
fig.savefig('plot/force_applied.png')
plt.close(fig)
Functions
def index_to_str()
-
Convert a integer into a string with the format XXX.
Expand source code
def index_to_str(j): ''' Convert a integer into a string with the format XXX. ''' if j < 10: return '00'+str(j) elif 10<=j and j< 100: return '0'+str(j) else : return str(j)
def read_vtk()
-
Read the last vtk files to obtain data from MOOSE.
Expand source code
def read_vtk(dict_user, dict_sample, j_str): ''' Read the last vtk files to obtain data from MOOSE. Do not work calling yade. ''' eta_1_map_old = dict_sample['eta_1_map'].copy() c_map_old = dict_sample['c_map'].copy() L_eta1 = [] L_c = [] if not dict_sample['Map_known']: L_limits = [] L_XYZ = [] L_L_i_XYZ_used = [] else : L_XYZ = dict_sample['L_XYZ'] # iterate on the proccessors used for i_proc in range(dict_user['n_proc']): # name of the file to load namefile = 'vtk/pf_other_'+j_str+'_'+str(i_proc)+'.vtu' # load a vtk file as input reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(namefile) reader.Update() # Grab a scalar from the vtk file nodes_vtk_array = reader.GetOutput().GetPoints().GetData() eta1_vtk_array = reader.GetOutput().GetPointData().GetArray("eta1") c_vtk_array = reader.GetOutput().GetPointData().GetArray("c") #Get the coordinates of the nodes and the scalar values nodes_array = vtk_to_numpy(nodes_vtk_array) eta1_array = vtk_to_numpy(eta1_vtk_array) c_array = vtk_to_numpy(c_vtk_array) # map is not know if not dict_sample['Map_known']: # look for limits x_min = None x_max = None y_min = None y_max = None # save the map L_i_XYZ_used = [] # Must detect common zones between processors for i_XYZ in range(len(nodes_array)) : XYZ = nodes_array[i_XYZ] # Do not consider twice a point if list(XYZ) not in L_XYZ : L_XYZ.append(list(XYZ)) L_eta1.append(eta1_array[i_XYZ]) L_c.append(c_array[i_XYZ]) L_i_XYZ_used.append(i_XYZ) # set first point if x_min == None : x_min = list(XYZ)[0] x_max = list(XYZ)[0] y_min = list(XYZ)[1] y_max = list(XYZ)[1] # look for limits of the processor else : if list(XYZ)[0] < x_min: x_min = list(XYZ)[0] if list(XYZ)[0] > x_max: x_max = list(XYZ)[0] if list(XYZ)[1] < y_min: y_min = list(XYZ)[1] if list(XYZ)[1] > y_max: y_max = list(XYZ)[1] # Here the algorithm can be help as the mapping is known L_L_i_XYZ_used.append(L_i_XYZ_used) # save limits L_limits.append([x_min,x_max,y_min,y_max]) # map is known else : # the last term considered is at the end of the list if dict_sample['L_L_i_XYZ_used'][i_proc][-1] == len(nodes_array)-1: L_eta1 = list(L_eta1) + list(eta1_array) L_c = list(L_c) + list(c_array) # the last term considered is not at the end of the list else : L_eta1 = list(L_eta1) + list(eta1_array[dict_sample['L_L_i_XYZ_used'][i_proc][0]: dict_sample['L_L_i_XYZ_used'][i_proc][-1]+1]) L_c = list(L_c) + list(c_array[dict_sample['L_L_i_XYZ_used'][i_proc][0]: dict_sample['L_L_i_XYZ_used'][i_proc][-1]+1]) if not dict_sample['Map_known']: # plot processors distribution if 'processor' in dict_user['L_figures'] and not dict_user['remesh']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) # parameters title_fontsize = 20 for i_proc in range(len(L_limits)): limits = L_limits[i_proc] ax1.plot([limits[0],limits[1],limits[1],limits[0],limits[0]],[limits[2],limits[2],limits[3],limits[3],limits[2]], label='proc '+str(i_proc)) ax1.legend() ax1.set_xlabel('X (m)') ax1.set_ylabel('Y (m)') ax1.set_title('Processor i has the priority on i+1',fontsize = title_fontsize) fig.suptitle('Processors ditribution',fontsize = 1.2*title_fontsize) fig.tight_layout() fig.savefig('plot/processors_distribution.png') plt.close(fig) # the map is known dict_sample['Map_known'] = True dict_sample['L_L_i_XYZ_used'] = L_L_i_XYZ_used dict_sample['L_XYZ'] = L_XYZ # rebuild map from lists for i_XYZ in range(len(L_XYZ)): # find nearest node L_search = list(abs(np.array(dict_sample['x_L']-L_XYZ[i_XYZ][0]))) i_x = L_search.index(min(L_search)) L_search = list(abs(np.array(dict_sample['y_L']-L_XYZ[i_XYZ][1]))) i_y = L_search.index(min(L_search)) # rewrite map dict_sample['eta_1_map'][-1-i_y, i_x] = L_eta1[i_XYZ] dict_sample['c_map'][-1-i_y, i_x] = L_c[i_XYZ]
def compute_vertices()
-
From a phase map, compute vertices coordinates for polyhedral.
Expand source code
def compute_vertices(dict_user, dict_sample): ''' From a phase map, compute vertices coordinates for polyhedral. ''' # compute vertices for grain L_vertices_1 = interpolate_vertices(dict_sample['eta_1_map'], dict_sample['pos_1'], dict_user, dict_sample) # compute vertices for plate L_vertices_2 = ((min(dict_sample['x_L']), 0, 0,), (max(dict_sample['x_L']), 0, 0,), (max(dict_sample['x_L']), min(dict_sample['y_L']), 0,), (min(dict_sample['x_L']), min(dict_sample['y_L']), 0,), (min(dict_sample['x_L']), 0, 1,), (max(dict_sample['x_L']), 0, 1,), (max(dict_sample['x_L']), min(dict_sample['y_L']), 1,), (min(dict_sample['x_L']), min(dict_sample['y_L']), 1,)) # save data dict_save = { 'L_vertices_1': L_vertices_1, 'L_vertices_2': L_vertices_2 } with open('data/planes.data', 'wb') as handle: pickle.dump(dict_save, handle, protocol=pickle.HIGHEST_PROTOCOL) # compute sample height and vertical strain L_x_1, L_y_1 = tools.tuplet_to_list(L_vertices_1) # from tools.py sample_height = max(L_y_1) dict_user['L_sample_height'].append(sample_height) # compute sphericities AreaSphericity, DiameterSphericity, CircleRatioSphericity, PerimeterSphericity, WidthToLengthRatioSpericity = tools.compute_sphericities(L_vertices_1) # from tools.py # save and plot dict_user['L_AreaSphericity'].append(AreaSphericity) dict_user['L_DiameterSphericity'].append(DiameterSphericity) dict_user['L_CircleRatioSphericity'].append(CircleRatioSphericity) dict_user['L_PerimeterSphericity'].append(PerimeterSphericity) dict_user['L_WidthToLengthRatioSpericity'].append(WidthToLengthRatioSpericity) if 'sphericities' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_AreaSphericity'], label='Area sphericity') ax1.plot(dict_user['L_DiameterSphericity'], label='Diameter sphericity') ax1.plot(dict_user['L_CircleRatioSphericity'], label='Circle ratio sphericity') ax1.plot(dict_user['L_PerimeterSphericity'], label='Perimeter sphericity') ax1.plot(dict_user['L_WidthToLengthRatioSpericity'], label='Width/Length spericity') ax1.legend() plt.suptitle('Grain sphericities (G1)', fontsize=20) fig.tight_layout() fig.savefig('plot/sphericities.png') plt.close(fig)
def interpolate_vertices()
-
Interpolate vertices for polyhedral.
Expand source code
def interpolate_vertices(eta_i_map, center, dict_user, dict_sample): ''' Interpolate vertices for polyhedral. ''' map_phi = [] L_phi = [] for i_phi in range(dict_user['n_phi']): phi = 2*math.pi*i_phi/dict_user['n_phi'] L_phi.append(phi) map_phi.append([]) L_phi.append(2*math.pi) for i_x in range(len(dict_sample['x_L'])-1): for i_y in range(len(dict_sample['y_L'])-1): L_in = [] # list the nodes inside the grain if eta_i_map[-1-i_y , i_x] > 0.5 : L_in.append(0) if eta_i_map[-1-(i_y+1), i_x] > 0.5 : L_in.append(1) if eta_i_map[-1-(i_y+1), i_x+1] > 0.5 : L_in.append(2) if eta_i_map[-1-i_y , i_x+1] > 0.5 : L_in.append(3) if L_in != [] and L_in != [0,1,2,3]: center_mesh = (np.array([dict_sample['x_L'][i_x], dict_sample['y_L'][i_y]])+np.array([dict_sample['x_L'][i_x+1], dict_sample['y_L'][i_y+1]]))/2 u = (center_mesh-np.array(center))/np.linalg.norm(center_mesh-np.array(center)) # compute phi if u[1]>=0: phi = math.acos(u[0]) else : phi = 2*math.pi-math.acos(u[0]) # iterate on the lines of the mesh to find the plane intersection L_p = [] if (0 in L_in and 1 not in L_in) or (0 not in L_in and 1 in L_in):# line 01 x_p = dict_sample['x_L'][i_x] y_p = (0.5-eta_i_map[-1-i_y, i_x])/(eta_i_map[-1-(i_y+1), i_x]-eta_i_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.append(np.array([x_p, y_p])) if (1 in L_in and 2 not in L_in) or (1 not in L_in and 2 in L_in):# line 12 x_p = (0.5-eta_i_map[-1-(i_y+1), i_x])/(eta_i_map[-1-(i_y+1), i_x+1]-eta_i_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.append(np.array([x_p, y_p])) if (2 in L_in and 3 not in L_in) or (2 not in L_in and 3 in L_in):# line 23 x_p = dict_sample['x_L'][i_x+1] y_p = (0.5-eta_i_map[-1-i_y, i_x+1])/(eta_i_map[-1-(i_y+1), i_x+1]-eta_i_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.append(np.array([x_p, y_p])) if (3 in L_in and 0 not in L_in) or (3 not in L_in and 0 in L_in):# line 30 x_p = (0.5-eta_i_map[-1-i_y, i_x])/(eta_i_map[-1-i_y, i_x+1]-eta_i_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.append(np.array([x_p, y_p])) # compute the mean point p_mean = np.array([0,0]) for p in L_p : p_mean = p_mean + p p_mean = p_mean/len(L_p) # look phi in L_phi i_phi = 0 while not (L_phi[i_phi] <= phi and phi <= L_phi[i_phi+1]) : i_phi = i_phi + 1 # save p_mean in the map map_phi[i_phi].append(p_mean) L_vertices = () # interpolate plane (Least squares method) for i_phi in range(len(map_phi)): if map_phi[i_phi] != []: # mean vertices mean_v = np.array([0, 0]) for v_i in map_phi[i_phi]: mean_v = mean_v + v_i/len(map_phi[i_phi]) # save L_vertices = L_vertices + ((mean_v[0], mean_v[1], 0,),) L_vertices = L_vertices + ((mean_v[0], mean_v[1], 1),) return L_vertices
def control_force()
-
Control force applied in DEM with the contact volume.
Expand source code
def control_force(dict_user, dict_sample): ''' Control force applied in DEM with the contact volume. Because of the fact that convvex shape is not possible in Yade. ''' # determine the volume contact in Moose (etai ad j > 0.5) V_contact_moose = 0 for i_x in range(len(dict_sample['x_L'])): for i_y in range(len(dict_sample['y_L'])): if dict_sample['eta_1_map'][-1-i_y, i_x] > 0.5 and dict_sample['y_L'][i_y]<=0: V_contact_moose = V_contact_moose + (dict_sample['x_L'][1]-dict_sample['x_L'][0])*(dict_sample['y_L'][1]-dict_sample['y_L'][0])*1 # compare with the volume contact expected # in Yade, F=k*V and 1/k = 1/Y1 + 1/Y2 V_expected = 2*dict_user['force_applied_target']/dict_user['E'] # the comparison is important if multiple controls are done per one PFDEM iteration # if only only control is done, the adaptation of the force can be done always #if V_contact_moose < (1-dict_user['steady_state_detection'])*V_expected or (1+dict_user['steady_state_detection'])*V_expected < V_contact_moose: if True: # control the force applied dict_user['force_applied'] = dict_user['force_applied']*V_expected/V_contact_moose # save and plot dict_user['L_force_applied'].append(dict_user['force_applied']) if 'force_applied' in dict_user['L_figures']: fig, (ax1) = plt.subplots(1,1,figsize=(16,9)) ax1.plot(dict_user['L_force_applied']) plt.suptitle('Force applied in Yade (DEM)', fontsize=20) fig.tight_layout() fig.savefig('plot/force_applied.png') plt.close(fig)