Skip to content
Snippets Groups Projects
updateNodes.jl 14.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
    # Amira Abdel-Rahman
    # (c) Massachusetts Institute of Technology 2020
    
    # BASED ON https://github.com/jonhiller/Voxelyze
    
    
    function updateNodes!(dt,currentTimeStep,N_position, N_restrained,N_displacement,N_angle,N_currPosition,N_linMom,N_angMom,
            N_intForce,N_intMoment,N_force,N_fixedDisplacement,N_moment,N_orient,N_edgeID,N_edgeFirst,N_material,N_poissonStrain,
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
            E_intForce1,E_intMoment1,E_intForce2,E_intMoment2,E_axis, E_strain,E_material,E_maxStrain)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
    
        index = (blockIdx().x - 1) * blockDim().x + threadIdx().x
        stride = blockDim().x * gridDim().x
        ## @cuprintln("thread $index, block $stride")
        N,M=size(N_edgeID)
        for i = index:stride:N
            
            isFloorEnabled=floorEnabled();#todo make these arguments ??
            
            # @inbounds if lengthVector3(Vector3(convert(Float64,N_displacement[i].x), 
            #             convert(Float64,N_displacement[i].y),convert(Float64,N_displacement[i].z))) >1000.0 #todo ?? change this according to ratio
            #     # @cuprintln("DIVERGEDNODE!!!!!!!!!!")
            #     return 
            # end
            
            
            
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
            @inbounds if (N_restrained[i].x && N_restrained[i].y && N_restrained[i].z)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                @inbounds N_linMom[i]=Vector3(0,0,0)
                @inbounds N_angMom[i]=Vector3(0,0,0)
                @inbounds if(N_material[i].poisson)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    @inbounds N_poissonStrain[i]=strain(i,N_material[i].poisson,i, N_edgeID, N_edgeFirst, E_axis, E_strain, E_material,E_maxStrain, N_restrained[i], N_material[i])
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                end
                return
            elseif N_fixedDisplacement[i].x != 0.0 || N_fixedDisplacement[i].y != 0.0  ||  N_fixedDisplacement[i].z != 0.0
                @inbounds N_linMom[i]=Vector3(0,0,0)
                @inbounds N_angMom[i]=Vector3(0,0,0)
                @inbounds if(N_material[i].poisson)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    @inbounds N_poissonStrain[i]=strain(i,N_material[i].poisson,i, N_edgeID, N_edgeFirst, E_axis, E_strain, E_material,E_maxStrain, N_restrained[i], N_material[i])
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                end
                @inbounds translate=externalDisplacement(currentTimeStep,N_position,N_fixedDisplacement[i])
                @inbounds N_currPosition[i]=N_currPosition[i]+translate
                @inbounds N_displacement[i]=N_displacement[i]+translate
    
            else
                
                for j in 1:M
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    @inbounds if (N_edgeID[i,j]!=-1 && !isFailed(E_maxStrain[N_edgeID[i,j]],E_material[N_edgeID[i,j]]))
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                        #@cuprintln("i $i, j $j, N_edgeID[i,j] $temp")
                        @inbounds N_intForce[i]=ifelse(N_edgeFirst[i,j], N_intForce[i]+E_intForce1[N_edgeID[i,j]], N_intForce[i]+E_intForce2[N_edgeID[i,j]] )
                        @inbounds N_intMoment[i]=ifelse(N_edgeFirst[i,j], N_intMoment[i]+E_intMoment1[N_edgeID[i,j]], N_intMoment[i]+E_intMoment2[N_edgeID[i,j]] )
                    end
                
                end
                
                FloorStaticFriction=false; 
                
                prec=1e8
                #get properties
                @inbounds E=roundd(N_material[i].E,prec)
                @inbounds nomSize=roundd(N_material[i].nomSize,prec)
                @inbounds mass=roundd(N_material[i].mass,prec)
                @inbounds massInverse=roundd(N_material[i].massInverse,prec)
                
                @inbounds curForce = force(i,N_intForce[i],N_orient[i],N_force[i],N_position[i],currentTimeStep,N_material[i],N_linMom[i])
    
                fricForce = Vector3(curForce.x,curForce.y,curForce.z);
                if (isFloorEnabled)
                    @inbounds curForce,FloorStaticFriction=floorForce!(dt,curForce,N_currPosition[i],
                        Vector3(N_linMom[i].x,N_linMom[i].y ,N_linMom[i].z),FloorStaticFriction,N_material[i])
                    
                end
                
                fricForce = curForce-fricForce;
    
                # @cuprintln("dt $dt")
                # @cuprintln("massInverse $massInverse")
                
                
                #########################################
                
                # @inbounds N_intForce[i]=Vector3(0,0,0) #??
            
                
                @inbounds N_linMom[i]=N_linMom[i]+curForce*Vector3(dt,dt,dt) #todo make sure right
                @inbounds translate=N_linMom[i]*Vector3((dt*massInverse),(dt*massInverse),(dt*massInverse)) # ??massInverse
    
                
                
                ############################
                
                
                #we need to check for friction conditions here (after calculating the translation) and stop things accordingly
    
                @inbounds if (isFloorEnabled && floorPenetration( convert(Float64,N_currPosition[i].x),convert(Float64,N_currPosition[i].y),N_material[i].nomSize)>= 0.0 )#we must catch a slowing voxel here since it all boils down to needing access to the dt of this timestep.
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    work =convert(Float64,fricForce.x*translate.x + fricForce.z*translate.z); #F dot disp
                    @inbounds hKe = 0.5*massInverse*convert(Float64,(N_linMom[i].x*N_linMom[i].x + N_linMom[i].z*N_linMom[i].z)); #horizontal kinetic energy
    
                    if((hKe + work) <= 0.0) 
                        FloorStaticFriction=true; #this checks for a change of direction according to the work-energy principle
                    end
    
                    if(FloorStaticFriction)
                        #if we're in a state of static friction, zero out all horizontal motion
                        N_linMom[i]=Vector3(0.0 ,convert(Float64,N_linMom[i].y) ,0.0)
                        translate=Vector3(0.0 ,convert(Float64,translate.y) ,0.0)
                    end
                else
                    FloorStaticFriction=false
                end
    
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                if N_restrained[i].x
                    translate=Vector3(0.0 ,convert(Float64,translate.y) ,convert(Float64,translate.z))
                end
                if N_restrained[i].y
                    translate=Vector3(convert(Float64,translate.x) ,0.0 ,convert(Float64,translate.z))
                end
                if N_restrained[i].z
                    translate=Vector3(convert(Float64,translate.x) ,convert(Float64,translate.y) ,0.0)
                end
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                
                @inbounds N_currPosition[i]=N_currPosition[i]+translate
                @inbounds N_displacement[i]=N_displacement[i]+translate
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                
                
                # Rotation
                @inbounds curMoment = moment(N_intMoment[i],N_orient[i],N_moment[i],N_material[i],N_angMom[i]) 
                
                @inbounds N_intMoment[i]=Vector3(0,0,0) # do i really need it?
                @inbounds N_intForce[i]=Vector3(0,0,0) # do i really need it?
                
                @inbounds N_angMom[i]=N_angMom[i]+curMoment*Vector3(dt,dt,dt)
                
    
                @inbounds momentInertiaInverse=convert(Float64,N_material[i].momentInertiaInverse)
                # if i==10
                #     @cuprintln("momentInertiaInverse $momentInertiaInverse")
                # end
                # momentInertiaInverse=1.92e-6
    
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                @inbounds temp=FromRotationVector(N_angMom[i]*Vector3((dt*momentInertiaInverse),(dt*momentInertiaInverse),(dt*momentInertiaInverse)))
    
                
                @inbounds N_orient[i]=multiplyQuaternions(temp,N_orient[i])
    
                @inbounds N_angle[i]=ToRotationVector(N_orient[i])
            
                ####poisson
                @inbounds if(N_material[i].poisson)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    @inbounds N_poissonStrain[i]=strain(i,N_material[i].poisson,i, N_edgeID, N_edgeFirst, E_axis, E_strain, E_material,E_maxStrain, N_restrained[i], N_material[i])
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                end
            end
        end
        return
    end
    
    
    function run_updateNodes!(dt,currentTimeStep,N_position, N_restrained,N_displacement, N_angle,N_currPosition,
            N_linMom,N_angMom,N_intForce,N_intMoment,N_force,N_fixedDisplacement,N_moment,N_orient,N_edgeID,N_edgeFirst,N_material,N_poissonStrain,
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
            E_intForce1,E_intMoment1,E_intForce2,E_intMoment2,E_axis, E_strain,E_material,E_maxStrain)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
        N=length(N_intForce)
        numblocks = ceil(Int, N/256)
    
        CUDA.@sync begin
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
            @cuda threads=256 blocks=numblocks updateNodes!(dt,currentTimeStep,N_position, N_restrained,N_displacement, 
                N_angle,N_currPosition,N_linMom,N_angMom,N_intForce,N_intMoment,N_force,N_fixedDisplacement,N_moment,N_orient,N_edgeID,N_edgeFirst,N_material,N_poissonStrain,
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                E_intForce1,E_intMoment1,E_intForce2,E_intMoment2,E_axis, E_strain,E_material,E_maxStrain)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
        end
    end
    
    
    ############################
    
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
    function strain(i,poissonStrain,id,N_edgeID,N_edgeFirst, E_axis, E_strain,E_material,E_maxStrain,N_restrained,mat)
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
    	
    	###if no connections in the positive and negative directions of a particular axis, strain is zero
    	###if one connection in positive or negative direction of a particular axis, strain is that strain - ?? and force or constraint?
    	###if connections in both the positive and negative directions of a particular axis, strain is the average. 
    	
        # intStrRet= [0.0, 0.0, 0.0] ###intermediate strain return value. axes according to linkAxis enum
    	# numBondAxis = [0,0,0]; ###number of bonds in this axis (0,1,2). axes according to linkAxis enum
        # tension = [false,false,false];
    
        intStrRet1=0.0
        intStrRet2=0.0
        intStrRet3=0.0
    
        numBondAxis1=0.0
        numBondAxis2=0.0
        numBondAxis3=0.0
    
        tension1=false
        tension2=false
        tension3=false
    
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
        fixed=N_restrained.x
    
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
        N,M=size(N_edgeID)
        for j in 1:M
            @inbounds linkID=N_edgeID[id,j]
            # @cuprintln("id $id, j $j, linkID $linkID")
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
            if (linkID!=-1 && !isFailed(E_maxStrain[linkID],E_material[linkID]))
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                # if (E_strain[j]!=0.0)
                    @inbounds axis= normalizeVector3(E_axis[linkID])
                    @inbounds strain1=axialStrain( N_edgeFirst[id,j],E_strain[linkID],E_material[linkID])
                    # if (E_strain[j]!=0.0)
                    #     @cuprint("strain1 $strain1")
                    # end
                    x= abs(convert(Float64,axis.x))*strain1 #todo change for general axis
                    y= abs(convert(Float64,axis.y))*strain1 #todo change for general axis
                    z= abs(convert(Float64,axis.z))*strain1 #todo change for general axis
                    if (axis.x!=0.0)
                        intStrRet1+=x
                        numBondAxis1+=1
                        # if(i==32)
                        #     @cuprintln("strain1 x $(strain1)")
                        # end
                    end
                    if (axis.y!=0.0)
                        intStrRet2+=y
                        numBondAxis2+=1
                    end
                    if (axis.z!=0.0)
                        intStrRet3+=z
                        numBondAxis3+=1
                    end
                # end
            end
        end
        # @cuprintln("intStrRet 11 x $(intStrRet1*1e6) *1e-6, y $(intStrRet2*1e6) *1e-6, z $(intStrRet3*1e6) *1e-6")
        # for i =1:3
            if (numBondAxis1>1.0) 
                intStrRet1=intStrRet1 /numBondAxis1 ###average
            end
            if (poissonStrain)
                tension1 = ((numBondAxis1==2.0) || (fixed&&numBondAxis1==1.0))
                    #(ext && (numBondAxis[i]==1 && (ext.isFixed((dofComponent)(1<<i)) || ext.force()[i] != 0)))); #if both sides pulling, or just one side and a fixed or forced voxel...
            end
    
            if (numBondAxis2>1.0) 
                intStrRet2=intStrRet2 /numBondAxis2 ###average
            end
            if (poissonStrain)
                tension2 = ((numBondAxis2==2.0) || (fixed&&numBondAxis2==1.0))
                    #(ext && (numBondAxis[i]==1 && (ext.isFixed((dofComponent)(1<<i)) || ext.force()[i] != 0)))); #if both sides pulling, or just one side and a fixed or forced voxel...
            end
    
            if (numBondAxis3>1.0) 
                intStrRet3=intStrRet3 /numBondAxis3 ###average
            end
            if (poissonStrain)
                tension3 = ((numBondAxis3==2.0) || (fixed&&numBondAxis3==1.0))
                    #(ext && (numBondAxis[i]==1 && (ext.isFixed((dofComponent)(1<<i)) || ext.force()[i] != 0)))); #if both sides pulling, or just one side and a fixed or forced voxel...
            end
        # end
    
        # if(i==32)
        #     @cuprintln("intStrRet 1 x $(intStrRet1) , y $(intStrRet2) , z $(intStrRet3)")
        #     @cuprintln("numBondAxis x $(numBondAxis1) , y $(numBondAxis2) , z $(numBondAxis3) ")
        # end
    
    	if (poissonStrain)
    		if (!(tension1 && tension2 && tension3 )) ###if at least one isn't in tension
    			add = 0.0;
                # for i =1:3
                    if (tension1) 
    
                        add=add+intStrRet1
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    end
                    if (tension2) 
    
                        add=add+intStrRet2
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    end
                    if (tension3) 
    
                        add=add+intStrRet3
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
                    end
                # end
                # @cuprintln("add x $(add*1e6)")
                # @cuprintln("mat.nu x $(mat.nu)")
    
                # value =  pow((1.0 + add),(-mat.nu))-1.0 #((1.0 + add)^(-mat.nu)) - 1.0;
                value = CUDA.pow( 1.0 + add, -mat.nu) - 1.0;
    
    Amira Abdel-Rahman's avatar
    Amira Abdel-Rahman committed
    
                # if(i==32)
                #     @cuprintln("value x $(value)")
                #     @cuprintln("mat.nu x $(mat.nu)")
                #     @cuprintln("add x $(add)")
                # end
    
    
                # value =((1.0 + add)^(-roundd(mat.nu,10e5))) - 1.0;
                # @cuprintln("value x $(value*1e6)")
                # value=0.0
                # for i =1:3
                    if (!tension1) 
                        intStrRet1=value;
                    end
                    if (!tension2) 
                        intStrRet2=value;
                    end
                    if (!tension3) 
                        intStrRet3=value;
                    end
                # end   
            end
        end
    
        # if(i==32)
        #     @cuprintln("intStrRet 2 x $(intStrRet1*1e6) *1e-6, y $(intStrRet2*1e6) *1e-6, z $(intStrRet3*1e6) *1e-6")
        # end
    
        intStrRet= Vector3(intStrRet1,intStrRet2,intStrRet3); ###intermediate strain return value. axes according to linkAxis enum
        # @cuprintln("intStrRet x $(intStrRet1*1e6) *1e-6, y $(intStrRet2*1e6) *1e-6, z $(intStrRet3*1e6) *1e-6")
        # @cuprintln("numBondAxis x $(numBondAxis1) , y $(numBondAxis2) , z $(numBondAxis3) ")
        # if tension1
        #     tension1=1.0
        # else
        #     tension1=0.0
        # end
        # if tension2
        #     tension2=1.0
        # else
        #     tension2=0.0
        # end
        # if tension3
        #     tension3=1.0
        # else
        #     tension3=0.0
        # end
        # @cuprintln("tension x $(tension1) , y $(tension2) , z $(tension3) ")
    	return intStrRet
    end
    
    function axialStrain( positiveEnd,strain,mat)
        #strainRatio = pVPos->material()->E/pVNeg->material()->E;
        strainRatio=convert(Float64,mat.strainRatio)
        # positiveEnd=true
        return positiveEnd ? 2.0 *strain*strainRatio/(1.0+strainRatio) : 2.0*strain/(1.0+strainRatio)
    end