# -*- coding: utf-8
'''
Created on %(date)
@author:Yujin Wang
'''
import os
import numpy as np,pandas as pd,matplotlib.pylab as plt
from funmodule import *
from Copyright import *
class basic():
	"""docstring for basic"""
	def __init__(self, *args):
		self.src = args[0]
		self.des = args[1]
		self.flag1 = args[2]
		self.flag2 = args[3]
		self.flag3 = args[4]
        
@statement
class denting_main(basic):
    ''' This is the denting analysis for every part.'''
    @property
    def denting_main(self):
        i=1
        for line in open(self.flag1):
            print ('**************%i point *************' %(i))
            line = line.split(' ')
            x = int(line[0]); o = int(line[1]); y =int(line[2])
            self.flag1 = [o,x,y]
            self.flag2 = self.des + '/denting_' + str(i) + '.inp'
            self.inp_gen
            print ('**************%i point end***********' %(i))
            i  += 1

    @property
    def inp_gen(self):
        #Initialization#
        '''There are two ways to solve the convergence problem, one is add
        ADJUST = 0.01 behind the "*Contact Initialization Data" to define
        "INITIAL CLEARANCE" and "SEARCH REGION". However, the two ways cannot
        promise that the solution process must be convergent, so you must check
        and try'''
        list_grid = self.flag1
        iselem = 0
        isall = 3
        isset = 0
        isstart = 0
        isfind = 0
        flag_load = 0
        node_search = 0
        oxy = [[0,0,0],[0,0,0],[0,0,0]]
        fout = open(self.flag2,'w')
        fout.write('**\n\**ABAQUS FILE IS GENERATED BY YOKINGPY\n\
            **chaos1984@163.com\n')
        for line in open(self.src,'r'):
            if '**' in line:
                continue
            elif '*NODE' in line:
                fout.write(line)
                node_search = 1
                continue
            elif (node_search == 1 and isall > 1):
                fout.write(line)
                line = line.split(',')
                if int(line[0] in list_grid):
                    grid_pos = [float(i) for i in line[1:]]
                    oxy[list_grid.index(int(line[0]))] = grid_pos
                    isall = 1

            elif ('*ELEMENT,TYPE = S' in line):
                fout.write(line)
                iselem = 1
                continue

            elif (iselem == 1 and ' ' + str(list_grid[0]) + ',' in line[10:]):
                fout.write(line)
                data = line.split(',')
                if 6 > len(data) > 4:
                    slave_element_id = data[0].strip()
                    iselem = 0

            elif ('*ELSET, ELSET=' in line and isfind == 0):
                isset = 1
                fout.write(line)
                master = line[(line.index('=')+1):-1]
                continue

            elif (isset == 1 and slave_element_id in line):
                try:
                    print ('The slave surface ID is: %s' %master)
                    fout.write(line)
                    isset = 0
                    isfind = 1
                except:
                    print ('ERROR: Denting: inp_gen: isset is not found.\n')

            elif ('MATERIAL' in line and isstart == 0):
                loc,alpha,beta = local_coor(oxy)
                fout.write('*SYSTEM\n')
                temp = '%11f,%11f,%11f,%11f,%11f,%11f\n%11f,%11f,%11f\n'
                fout.write(temp)
                fout.write('*NODE , SYSTEM = R\n\
                    4,  0,0     ,   0.0    ,  0.0   \n\
                    *NSET, NSET = sphere\n\
                    4,\n\
                    *TRANSFORM, TYPE=R, NSET=sphere\n')
                temp = '%11f,%11f,%11f,%11f,%11f,%11f\n'
                fout.write(temp)
                fout.write('*RIGID BODY, REF NODE=		4,ANALYTICAL SURFACE = sp1\n\
                    *SURFACE INTERACTION,NAME = INT\n\
                    *SURFACE BEHIVIOR,PRESSURE-OVERCLOSURE = HARD\n\
                    *CONTACT PAIR, INTERACTION=INT\n\
                    hood,sp1\n\
                    *SURFACE, NAME = hood, TYPE = ELEMENT\n' )
                #you can add a "ADJUST = value", but it is not recommended, because it will change the local geom which influence the structural stiffness totally.
                temp = '%s,SPOS\n' %master
                fout.write(temp)
                fout.write('*SURFACE, NAME = sp1, TYPE = REVOLUTION\n')
                temp = '%11f,%11f,%11f,%11f,%11f,%11f\n'
                fout.write(temp)
                fout.write('	START,	0.0,	12.700001\n\
                    CIRCL,	12.700001,	0.0,	0.0,	0.0\n\
                    *Contact Initialization Data,	name=CInt-1,	SEARCH ABOVE=1,	INITIAL CLEARANCE = 0, SEARCH BELOW = 10.,SEARCH ABOVE = 10.\n')
                fout.write(line)
                isstart = 1
            elif '*BOUNDARY' in line:
                if flag_load == 0:
                    flag_load = 1
                    fout.write('*CLOAD\n\
                        4,3,-130.0			\n')
                    fout.write(line)
                    temp = '		4,1,2,0.0\n\
                    4,4,6,0.0\n'
                    fout.write(line)
                else:
                    fout.write(line)
        fout.close()

        def local_coor(oxy):
            '''Calculate the loc_coordinate!'''
            loc_oxy = []
            norm = cross_vector(oxy[0],oxy[1],oxy[2])
            loc_oxy.append(norm_trans(-1*norm,12.7,oxy[0]))
            beta = norm_vector(np.subtract(oxy[1],oxy[0]))
            alpha = norm_vector(np.subtract(oxy[3],oxy[0]))
            loc_oxy.append(list(loc_oxy[0] + alpha))
            loc_oxy.append(list(loc_oxy[0] + beta))
            print ('The distanace between origin_oxy and local_oxy is %f' %(distance(oxy[0],loc_oxy[0])))
            return local_oxy,alpha,beta

        class Aba_information(basic):
            '''Collect the inp file information, egs. NODE,NODE SET AND ELEMENT'''
            def data_ectract(self,partname):
                printtime()
                print ('Start data extract')
                self.NODE = {}
                self.NSET = {}
                self.ELEM = {}
                isNODEStart = 0
                isNSETStart = 0
                isELEMStart = 0
                for line in open(self.src):
                #######	EXTRACT NODE DATA  ############
                    if ('*NODE\n' in line):
                        isNODEStart = 1
                        continue
                    elif ('*' not in line and isNODEStart ==1):
                        isNODEStart = 0

                ###### EXTRACT ELEMENT DATA ###########
                    elif ('*ELEMENT,TYPE=' in line and partname in line):
                        isELEMStart = 1
                    elif ('*' not in line and isELEMStart == 1):
                        data = string_split(line,',')
                        self.ELEM[int(data[0])] = [int(i) for i in data[1:]]
                    elif ('*' in line and isELEMStart == 1):
                        isELEMStart = 0
                ###### EXTRACT NSET DATA  ############
                    elif ('*NSET' in line):
                        NSETName = string_split(line,'=')[1][:-1]
                        isNSETStart = 1
                        self.NSET[NSETName] = []
                        continue
                    elif ('*' in line and isNSETStart == 1):
                        isNSETStart = 0

		def force_subs(self,force_point,load,outputfile):
			'''subs the new force
			force_point	 = center force
			load = force in three dimension'''
			isForceStart = 0
			isNSETStart = 0
			fout = open(outputfile,'w')
			for line in open(self.src):
				if '*CLOAD' in line:
					isForceStart = 1
					fout.write(line)
					i = 0
				elif ('*' not in line and isForceStart == 1):
					line = '	%d,%d,%10.6f\n' %(force_point,(i+1),load[(i)])
					fout.write(line)
					i += 1
					if i==3:
						isForceStart = 0
					elif '=node_disp' in line:
						isNSETStart = 1
						fout.write(line)
					elif '*' not in line and isNSETStart ==1:
						line ='%d,\n' %force_point
						fout.write(line)
						isNSETStart = 0
					else:
						fout.write(line)
				printtime()
				print '%s is output!' %outputfile 

		def Aba_result(basic):
			@property
			def maxvalue(self):
				datfile = self.src.replace('.inp','dat')
				for line in open(datfile):
					if ' MAXIMUM ' in line:
						string = string_split(line,' ')
						umag = disp_mag([float(j) for j in string[1:4]])
						printtime()
						print ('Displacement: %10.5f' %umag)
						return umag

		def Abaqus_run(runfile,path):
			'''ÁBQ**.bat calculate'''
			batfile = open(path+'run.bat','w')
			string = 'cd %s \n\
			abq6101.bat job=%s input=%s interactive cpu=16' %(path,runfile,path+runfile)
			batfile.write(string)
			batfile.close()
			stafile = runfile.replace('.inp','.sta')
			os.system(path+'run.bat')
			isComplete = 0
			printtime()
			print ('Calculation start!')
			while (isComplete == 1):
				for line in open(stafile):
					if ('THE ANALYSIS HAS COMPLETED SUCCESSFULLY' in line):
						isComplete = 1
			printtime()
			print ('Calculation completed!')

			class conc_force():
				'''Pre/Solve/Post 4 concentrated force.'''
				def __init__(self,*args):
					self.path = args[0]
					self.node = args[1]
					self.elem = args[2]
					self.fp = args[3]
					self.load = args[4]

				def force_inp(self,obj):
					print (self.path)
					oxy = node_syst(oxy[0],oxy[1],oxy[2])
					force = self.load * norm
					print ('The force(-130 N) at the node is divided into three sub-force in global coordinate\n X: %f\tY: %f\tZ: %f\t' %(force[0],force[1],force[2]))
					self.filename = 'opt_%s.inp' %(self.fp)
					self.filedir = self.path +self.filename
					obj.force_subs(self.fp,force,self.filedir)

					def post_dis(self):
						res = Aba_result(self.filedir,0,0,0,0)
						print ('The result file is %s' %(self.filedir))
						return res.maxvalue
