#!/usr/bin/python
# -*- coding: utf-8 -*-
# Created by Burak ER
from yade.deformableelementsutils import *;

O=Omega()

pressure=70e7;# N/m^2
wx=1;#m
wy=1;#m
wz=1;#m
## Create deformable elements internal materials and interaction element material

try:
	mat=LinIsoRayleighDampElastMat(label='aluminiummaterial');
except NameError:
	print("\n[93mDid you compile yade with cmake option -DENABLE_FEMLIKE=1 ?[0m\n")
	import sys
	sys.exit()

intermat=LinCohesiveStiffPropDampElastMat(label='intermat')

intermat.youngmodulus=70e11;

mat.density=2700;

mat.beta=0.05;

mat.alpha=0.05;

mat.youngmodulus=70e9;

O.materials.append(intermat)

O.materials.append(mat)




#create points of a cube with number of 8 points
p0=Vector3([0, 0 ,0]);
p1=Vector3([0, wy, 0]);
p2=Vector3([wx ,0 ,0]);
p3=Vector3([0, 0 ,wz]);
p4=Vector3([0, wy, wz]);
p5=Vector3([wx, wy, 0]);
p6=Vector3([wx, 0 ,wz]);
p7=Vector3([wx, wy ,wz]);

nodesofelement1=[p0,p1,p2,p3];
nodesofelement2=[p3,p4,p1,p7];
nodesofelement3=[p2,p5,p1,p7];
nodesofelement4=[p7,p2,p3,p6];
nodesofelement5=[p1,p2,p3,p7];





noderadius=0.1*(0.75*tetrahedronvolume(nodesofelement1))**0.33333333;

[elbody1, nodebodies1]=tetrahedral_element(mat,nodesofelement1,Lin4NodeTetra,radius=noderadius)
[elbody2, nodebodies2]=tetrahedral_element(mat,nodesofelement2,Lin4NodeTetra,radius=noderadius)
[elbody3, nodebodies3]=tetrahedral_element(mat,nodesofelement3,Lin4NodeTetra,radius=noderadius)
[elbody4, nodebodies4]=tetrahedral_element(mat,nodesofelement4,Lin4NodeTetra,radius=noderadius)
[elbody5, nodebodies5]=tetrahedral_element(mat,nodesofelement5,Lin4NodeTetra,radius=noderadius)



interfaceelementpairs=[];
#interface of 1-5
interfaceelementpairs.append([nodebodies1[1], nodebodies5[0]]);
interfaceelementpairs.append([nodebodies1[2], nodebodies5[1]]);
interfaceelementpairs.append([nodebodies1[3], nodebodies5[2]]);

[elbodyinter, nodebodiesinter]=interaction_element(intermat,interfaceelementpairs,Lin4NodeTetra_Lin4NodeTetra_InteractionElement);

#interface of 2-5
interfaceelementpairs=[];
interfaceelementpairs.append([nodebodies2[0], nodebodies5[2]]);
interfaceelementpairs.append([nodebodies2[2], nodebodies5[0]]);
interfaceelementpairs.append([nodebodies2[3], nodebodies5[3]]);

[elbodyinter, nodebodiesinter]=interaction_element(intermat,interfaceelementpairs,Lin4NodeTetra_Lin4NodeTetra_InteractionElement);

#interface of 3-5
interfaceelementpairs=[];
interfaceelementpairs.append([nodebodies3[0], nodebodies5[1]]);
interfaceelementpairs.append([nodebodies3[2], nodebodies5[0]]);
interfaceelementpairs.append([nodebodies3[3], nodebodies5[3]]);

[elbodyinter, nodebodiesinter]=interaction_element(intermat,interfaceelementpairs,Lin4NodeTetra_Lin4NodeTetra_InteractionElement);

#interface of 3-5
interfaceelementpairs=[];
interfaceelementpairs.append([nodebodies3[0], nodebodies5[1]]);
interfaceelementpairs.append([nodebodies3[2], nodebodies5[0]]);
interfaceelementpairs.append([nodebodies3[3], nodebodies5[3]]);
[elbodyinter, nodebodiesinter]=interaction_element(intermat,interfaceelementpairs,Lin4NodeTetra_Lin4NodeTetra_InteractionElement);

#interface of 4-5
interfaceelementpairs=[];
interfaceelementpairs.append([nodebodies4[0], nodebodies5[3]]);
interfaceelementpairs.append([nodebodies4[1], nodebodies5[1]]);
interfaceelementpairs.append([nodebodies4[2], nodebodies5[2]]);
[elbodyinter, nodebodiesinter]=interaction_element(intermat,interfaceelementpairs,Lin4NodeTetra_Lin4NodeTetra_InteractionElement);


# Time step determines the exiting period of the integrator since the integrator performs one step from current_time to current_time+dt; using many substeps for any value of dt; then stops. 
initpos0=O.bodies[nodebodies1[0].id].state.pos;



def applyforcetoelements():
	
		pos0=O.bodies[nodebodies3[0].id].state.pos;
		pos1=O.bodies[nodebodies3[1].id].state.pos;
		pos2=O.bodies[nodebodies3[2].id].state.pos;
		area1=0.5*((pos1-pos0).cross(pos2-pos0)).norm();


		pos0=O.bodies[nodebodies1[0].id].state.pos;
		pos1=O.bodies[nodebodies1[1].id].state.pos;
		pos2=O.bodies[nodebodies1[2].id].state.pos;
		area2=0.5*((pos1-pos0).cross(pos2-pos0)).norm();


		Traction=area1*pressure;

		O.forces.addF(nodebodies3[0].id,Vector3(0,0,-(0.3*Traction)));
		O.forces.addF(nodebodies3[1].id,Vector3(0,0,-(0.3*Traction)));
		O.forces.addF(nodebodies3[2].id,Vector3(0,0,-(0.3*Traction)));


		
		Traction=area2*pressure;

		O.forces.addF(nodebodies1[0].id,Vector3(0,0,-(0.3*Traction)));
		O.forces.addF(nodebodies1[1].id,Vector3(0,0,-(0.3*Traction)));
		O.forces.addF(nodebodies1[2].id,Vector3(0,0,-(0.3*Traction)));

def fixboundryelements():
	
	nodebodies1[3].state.blockedDOFs='xyzXYZ'
	nodebodies2[0].state.blockedDOFs='xyzXYZ'
	nodebodies2[1].state.blockedDOFs='xyzXYZ'
	nodebodies2[3].state.blockedDOFs='xyzXYZ'
	nodebodies3[3].state.blockedDOFs='xyzXYZ'
	nodebodies4[0].state.blockedDOFs='xyzXYZ'
	nodebodies4[2].state.blockedDOFs='xyzXYZ'
	nodebodies4[3].state.blockedDOFs='xyzXYZ'
	nodebodies5[2].state.blockedDOFs='xyzXYZ'
	nodebodies5[3].state.blockedDOFs='xyzXYZ'


fixboundryelements();


def addplot():
	vecpos=(O.bodies[nodebodies1[0].id].state.pos-initpos0)
	plot.addData(displacement=abs(vecpos[2]),time=O.time)





 ##integratoreng=RungeKuttaCashKarp54Integrator([
 ##	    ForceResetter(),

	    ## Apply internal force to the deformable elements and internal force of the interaction element	 
 ##	    FEInternalForceEngine([If2_Lin4NodeTetra_LinIsoRayleighDampElast(),If2_2xLin4NodeTetra_LinCohesiveStiffPropDampElastMat()]),

 ##	    PyRunner(virtPeriod=1e-99,command='applyforcetoelements()'),
	  

 ##])

 ##O.engines=[integratoreng,
 ##  PyRunner(iterPeriod=1,command='addplot()')
 ##]

 ##integratoreng.rel_err=1e-3;

 ##integratoreng.abs_err=1e-3;
O.engines=[ForceResetter(),
	PyRunner(virtPeriod=1e-99,command='applyforcetoelements()'), 
	## Apply internal force to the deformable elements and internal force of the interaction element	
	FEInternalForceEngine([If2_Lin4NodeTetra_LinIsoRayleighDampElast(),If2_2xLin4NodeTetra_LinCohesiveStiffPropDampElastMat()]),
	NewtonIntegrator(damping=0,gravity=[0,0,0]),
	PyRunner(virtPeriod=1e-99,command='addplot()'), 
];




O.dt=0.5e-7;

from yade import plot

plot.plots={'time':'displacement'}

plot.plot(subPlots=False)

try:
	from yade import qt
	qt.View()
	qt.Controller()
except ImportError: pass

