Ejemplo n.º 1
0
    def linearize(self, params, unknowns, resids):

        # rename
        rho = params['rho']
        U = params['U']
        d = params['d']
        mu = params['mu']
        beta = params['beta']

        # dynamic pressure
        q = 0.5*rho*U**2

        # Reynolds number and drag
        if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
            cd = params['cd_usr']
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)

        # derivatives
        dq_dU = rho*U
        const = (dq_dU*cd + q*dcd_dRe*rho*d/mu)*d
        dPx_dU = const*cosd(beta)
        dPy_dU = const*sind(beta)

        const = (cd + dcd_dRe*Re)*q
        dPx_dd = const*cosd(beta)
        dPy_dd = const*sind(beta)

        n = len(params['z'])

        zeron = np.zeros((n, n))

        J = {}
        J['windLoads.Px', 'U'] = np.diag(dPx_dU)
        J['windLoads.Px', 'z'] = zeron
        J['windLoads.Px', 'd'] = np.diag(dPx_dd)

        J['windLoads.Py', 'U'] = np.diag(dPy_dU)
        J['windLoads.Py', 'z'] = zeron
        J['windLoads.Py', 'd'] = np.diag(dPy_dd)

        J['windLoads.Pz', 'U'] = zeron
        J['windLoads.Pz', 'z'] = zeron
        J['windLoads.Pz', 'd'] = zeron

        J['windLoads.qdyn', 'U'] = np.diag(dq_dU)
        J['windLoads.qdyn', 'z'] = zeron
        J['windLoads.qdyn', 'd'] = zeron

        J['windLoads.z', 'U'] = zeron
        J['windLoads.z', 'z'] = np.eye(n)
        J['windLoads.z', 'd'] = zeron

        return J
Ejemplo n.º 2
0
    def linearize(self, params, unknowns, resids):

        # rename
        rho = params['rho']
        U = params['U']
        d = params['d']
        mu = params['mu']
        beta = params['beta']

        # dynamic pressure
        q = 0.5*rho*U**2

        # Reynolds number and drag
        if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
            cd = params['cd_usr']
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)

        # derivatives
        dq_dU = rho*U
        const = (dq_dU*cd + q*dcd_dRe*rho*d/mu)*d
        dPx_dU = const*cosd(beta)
        dPy_dU = const*sind(beta)

        const = (cd + dcd_dRe*Re)*q
        dPx_dd = const*cosd(beta)
        dPy_dd = const*sind(beta)

        n = len(params['z'])

        zeron = np.zeros((n, n))

        J = {}
        J['windLoads.Px', 'U'] = np.diag(dPx_dU)
        J['windLoads.Px', 'z'] = zeron
        J['windLoads.Px', 'd'] = np.diag(dPx_dd)

        J['windLoads.Py', 'U'] = np.diag(dPy_dU)
        J['windLoads.Py', 'z'] = zeron
        J['windLoads.Py', 'd'] = np.diag(dPy_dd)

        J['windLoads.Pz', 'U'] = zeron
        J['windLoads.Pz', 'z'] = zeron
        J['windLoads.Pz', 'd'] = zeron

        J['windLoads.qdyn', 'U'] = np.diag(dq_dU)
        J['windLoads.qdyn', 'z'] = zeron
        J['windLoads.qdyn', 'd'] = zeron

        J['windLoads.z', 'U'] = zeron
        J['windLoads.z', 'z'] = np.eye(n)
        J['windLoads.z', 'd'] = zeron

        return J
Ejemplo n.º 3
0
    def provideJ(self):

        J = np.array([[
            cosd(self.precone),
            sind(self.precone),
            (-self.Rtip * sind(self.precone) +
             self.precurveTip * sind(self.precone)) * pi / 180.0
        ]])

        return J
Ejemplo n.º 4
0
    def solve_nonlinear(self, params, unknowns, resids):

        rho = params['rho']
        U = params['U']
        d = params['d']
        mu = params['mu']
        beta = params['beta']

        # dynamic pressure
        q = 0.5*rho*U**2

        # Reynolds number and drag
        if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)
        else:
            cd = params['cd_usr']
            Re = 1.0
            dcd_dRe = 0.0
        Fp = q*cd*d

        # components of distributed loads
        Px = Fp*cosd(beta)
        Py = Fp*sind(beta)
        Pz = 0*Fp

        # pack data
        unknowns['windLoads_Px'] = Px
        unknowns['windLoads_Py'] = Py
        unknowns['windLoads_Pz'] = Pz
        unknowns['windLoads_qdyn'] = q
        unknowns['windLoads_z'] = params['z']
        unknowns['windLoads_beta'] = beta
Ejemplo n.º 5
0
    def execute(self):

        rho = self.rho
        U = self.U
        d = self.d
        mu = self.mu
        beta = self.beta

        # dynamic pressure
        q = 0.5*rho*U**2

        # Reynolds number and drag
        if self.cd_usr:
            cd = self.cd_usr
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)
        Fp = q*cd*d

        # components of distributed loads
        Px = Fp*cosd(beta)
        Py = Fp*sind(beta)
        Pz = 0*Fp

        print "CommonSE Px (Wind): ", Px

        # pack data
        self.windLoads.Px = Px
        self.windLoads.Py = Py
        self.windLoads.Pz = Pz
        self.windLoads.qdyn = q
        self.windLoads.z = self.z
        self.windLoads.beta = beta

        # derivatives
        self.dq_dU = rho*U
        const = (self.dq_dU*cd + q*dcd_dRe*rho*d/mu)*d
        self.dPx_dU = const*cosd(beta)
        self.dPy_dU = const*sind(beta)

        const = (cd + dcd_dRe*Re)*q
        self.dPx_dd = const*cosd(beta)
        self.dPy_dd = const*sind(beta)
Ejemplo n.º 6
0
    def execute(self):

        rho = self.rho
        U = self.U
        d = self.d
        mu = self.mu
        beta = self.beta

        # dynamic pressure
        q = 0.5 * rho * U**2

        # Reynolds number and drag
        if self.cd_usr:
            cd = self.cd_usr
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho * U * d / mu
            cd, dcd_dRe = cylinderDrag(Re)
        Fp = q * cd * d

        # components of distributed loads
        Px = Fp * cosd(beta)
        Py = Fp * sind(beta)
        Pz = 0 * Fp

        # pack data
        self.windLoads.Px = Px
        self.windLoads.Py = Py
        self.windLoads.Pz = Pz
        self.windLoads.qdyn = q
        self.windLoads.z = self.z
        self.windLoads.beta = beta

        # derivatives
        self.dq_dU = rho * U
        const = (self.dq_dU * cd + q * dcd_dRe * rho * d / mu) * d
        self.dPx_dU = const * cosd(beta)
        self.dPy_dU = const * sind(beta)

        const = (cd + dcd_dRe * Re) * q
        self.dPx_dd = const * cosd(beta)
        self.dPy_dd = const * sind(beta)
Ejemplo n.º 7
0
    def solve_nonlinear(self, params, unknowns, resids):

        rho = params['rho']
        U = params['U']
        d = params['d']
        mu = params['mu']
        beta = params['beta']

        if not (params['rho'] == 0. or all(params['U'] == 0.) or params['mu'] == 0.):

            # dynamic pressure
            q = 0.5*rho*U**2

            # Reynolds number and drag
            if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
                Re = rho*U*d/mu
                cd, dcd_dRe = cylinderDrag(Re)
            else:
                cd = params['cd_usr']
                Re = 1.0
                dcd_dRe = 0.0
            Fp = q*cd*d

            # components of distributed loads
            Px = Fp*cosd(beta)
            Py = Fp*sind(beta)
            Pz = 0*Fp

            # pack data
            unknowns['windLoads_Px'] = Px
            unknowns['windLoads_Py'] = Py
            unknowns['windLoads_Pz'] = Pz
            unknowns['windLoads_qdyn'] = q
            unknowns['windLoads_beta'] = beta
        
        unknowns['windLoads_z'] = params['z']
        unknowns['windLoads_d'] = params['d']
Ejemplo n.º 8
0
    def provideJ(self):

        J = np.array([[cosd(self.precone), sind(self.precone),
            (-self.Rtip*sind(self.precone) + self.precurveTip*sind(self.precone))*pi/180.0]])

        return J
Ejemplo n.º 9
0
    def execute(self):

        self.R = self.Rtip*cosd(self.precone) + self.precurveTip*sind(self.precone)
Ejemplo n.º 10
0
    def execute(self):

        rho = self.rho
        U = self.U
        U0 = self.U0
        d = self.d
        zrel= self.z-self.wlevel
        mu = self.mu
        beta = self.beta
        beta0= self.beta0

        # dynamic pressure
        q = 0.5*rho*U**2
        q0= 0.5*rho*U0**2

        # Reynolds number and drag
        if self.cd_usr:
            cd = self.cd_usr*np.ones_like(self.d)
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)

        d = self.d
        mu = self.mu
        beta = self.beta

        # inertial and drag forces
        Fi = rho*self.cm*math.pi/4.0*d**2*self.A  # Morrison's equation
        Fd = q*cd*d
        Fp = Fi + Fd

        #FORCES [N/m] AT z=0 m
        idx0 = np.abs(zrel).argmin()  # closest index to z=0, used to find d at z=0
        d0 = d[idx0]  # initialize
        cd0 = cd[idx0]  # initialize
        if (zrel[idx0]<0.) and (idx0< (zrel.size-1)):       # point below water
            d0 = np.mean(d[idx0:idx0+2])
            cd0 = np.mean(cd[idx0:idx0+2])
        elif (zrel[idx0]>0.) and (idx0>0):     # point above water
            d0 = np.mean(d[idx0-1:idx0+1])
            cd0 = np.mean(cd[idx0-1:idx0+1])
        Fi0 = rho*self.cm*math.pi/4.0*d0**2*self.A0  # Morrison's equation
        Fd0 = q0*cd0*d0
        Fp0 = Fi0 + Fd0

        # components of distributed loads
        Px = Fp*cosd(beta)
        Py = Fp*sind(beta)
        Pz = 0.*Fp

        Px0 = Fp0*cosd(beta0)
        Py0 = Fp0*sind(beta0)
        Pz0 = 0.*Fp0

        #Store qties at z=0 MSL
        self.waveLoads.Px0 = Px0
        self.waveLoads.Py0 = Py0
        self.waveLoads.Pz0 = Pz0
        self.waveLoads.q0 = q0
        self.waveLoads.beta0 = beta0

        # pack data
        self.waveLoads.Px = Px
        self.waveLoads.Py = Py
        self.waveLoads.Pz = Pz
        self.waveLoads.qdyn = q
        self.waveLoads.z = self.z
        self.waveLoads.beta = beta
        self.waveLoads.d = d


        # derivatives
        self.dq_dU = rho*U
        const = (self.dq_dU*cd + q*dcd_dRe*rho*d/mu)*d
        self.dPx_dU = const*cosd(beta)
        self.dPy_dU = const*sind(beta)

        const = (cd + dcd_dRe*Re)*q + rho*self.cm*math.pi/4.0*2*d*self.A
        self.dPx_dd = const*cosd(beta)
        self.dPy_dd = const*sind(beta)

        const = rho*self.cm*math.pi/4.0*d**2
        self.dPx_dA = const*cosd(beta)
        self.dPy_dA = const*sind(beta)
Ejemplo n.º 11
0
    def execute(self):
        #simplify nomenclature
        psi_wi=self.towerWindLoads.beta[0]  #psi is stored in beta already, however for legs and piles it needs to be adjusted for psi
        psi_wa=self.towerWaveLoads.beta[0]
        twrZs=self.towerWindLoads.z
        pillegZs=self.pileLegWaveLoads.z
        pillegDs=self.pileLegWaveLoads.d
        nlegs=self.nlegs
        al_bat3D=self.al_bat3D
        VPFlag=self.VPFlag

        TwrRigidTop=(self.RNAinputs.CMoff[2] != 0.) and self.TwrRigidTop  #This makes sure we do not have TwrRigidTop=True with CMzoff=0., no length segment that is.

        pilendIDs=self.pilendIDs
        legndIDs=self.legndIDs
        twrndIDs=self.twrndIDs

        wdepth=self.wdepth

       #COSINE MATRIX FROM LOCAL TO GLOBAL COORDINATE SYSTEMS
        DIRCOSwind=np.array([ [cosd(psi_wi) , -sind(psi_wi) ,0.],
                          [    sind(psi_wi) , cosd(psi_wi),0.],
                          [    0.,                         0.,                      1.]])
        DIRCOSwave=np.array([ [cosd(psi_wa) , -sind(psi_wa) ,0.],
                          [   sind(psi_wa) ,   cosd(psi_wa),0.],
                          [     0.,                         0.,                      1.]])

        #I need to get the right node IDs to be able to assign forces for Frame3DD

        #Get the values of the loads at the nodes of pile and leg 1
        #for the other legs, the wdrag is going to be the same

        if nlegs== 4: #Diagonal loading condition ONLY for the time being
            pileidx=np.array([])  #Initialize in case empty piles
            if pilendIDs.size:
                pileidx=pilendIDs[0:pilendIDs.size/nlegs] #np.arange(Pilemems[0,0],Pilemems[-1,1]/nlegs+1)-1   #indices of pile 1

            legidx=legndIDs[0:legndIDs.size/nlegs]    #legidx=np.arange(Legmems[0,0],Legmems[-1,1]/nlegs+1)-1 #indices of leg 1

            deltaz=((np.roll(pillegZs,-1)-pillegZs)/2)[0:-1]  #these are the appropriate 1/2 deltazs for the entire pile-leg assembly
            deltaz=np.hstack((deltaz[0],(np.roll(deltaz,-1)+deltaz)[0:-1],deltaz[-1]))  #This is the actual DeltaZ to be assigned at each node starting from the 2nd and ending at the one before last

            #Correct the delta z for the node just below water to avoid jumps in loading - use refined mesh however
            #idx_bw=np.nonzero(pillegZs<= wdepth)[0][-1] #CJB- Original code. Modified line below
            idx_bw=np.nonzero(pillegZs<= 0)[0][-1] #CJBe THe MSL is now at z=0, not z=wdepth
            #Also Attempt at using load at z=0
            ###Px0=self.pileLegWaveLoads.Px_i0overd2*pillegDs[idx_bw]**2+self.pileLegWaveLoads.Px_d0overd*pillegDs[idx_bw]
            ###Py0=self.pileLegWaveLoads.Py_i0overd2*pillegDs[idx_bw]**2+self.pileLegWaveLoads.Py_d0overd*pillegDs[idx_bw]
            Px0=self.pileLegWaveLoads.Px0
            Py0=self.pileLegWaveLoads.Py0
            #deltaz0=(wdepth-pillegZs[idx_bw]) #CJB- Original code. Modified line below
            deltaz0=np.abs(0-pillegZs[idx_bw]) #CJBe
            #if (wdepth-pillegZs[idx_bw])> deltaz[idx_bw]/2.:  #point with its deltaz entriely below surface #CJB- Original code. Modified line below
            if np.abs(0-pillegZs[idx_bw])> np.abs(deltaz[idx_bw]/2.): #CJBe Remove wdepth
                deltaz0 -= deltaz[idx_bw]/2.  #note deltaz0 before deltaz as deltaz gets modified
                #deltaz[idx_bw]=deltaz[idx_bw]/2. -(pillegZs[idx_bw]-wdepth)
            else:
                deltaz[idx_bw]=deltaz[idx_bw]/2.

            waDrag0=np.sqrt(Px0**2.+Py0**2.)*deltaz0  #In case add this one to the original wDrag, or alternatively do awhat I do below, increasing Deltaz

            waDrag=np.sqrt(self.pileLegWaveLoads.Px**2.+self.pileLegWaveLoads.Py**2.)*deltaz #[N] forces from waves, considered normal to the sloping 1 leg.
            waDrag[idx_bw] += waDrag0

            wiDrag=np.sqrt(self.pileLegWindLoads.Px**2.+self.pileLegWindLoads.Py**2.)*deltaz * (np.cos(al_bat3D))**2 #[N] forces from wind normal to the sloping 1 leg. Wind is horizontal, that's why cos^2

            #Forces on legs 1 (and 3 though sign of Fz reversed)
            junk=np.zeros(waDrag.size)
            waDrag1_3=  (np.dot(DIRCOSwave , np.vstack((waDrag*np.cos(al_bat3D),junk,waDrag*np.sin(al_bat3D))))).T   #[n,3] [N] This is an approx for air drag, as it is not normal to the leg to begin with, but it makes it easier
            wiDrag1_3=  (np.dot(DIRCOSwind , np.vstack((wiDrag*np.cos(al_bat3D),junk,wiDrag*np.sin(al_bat3D))))).T   #[n,3] [N]

            #Forces on legs 2 (and 4), it is as if they were vertical
            waDrag2_4=  (np.dot(DIRCOSwave ,np.vstack((waDrag,junk, waDrag*0.)))).T #[n,3]  [N]
            wiDrag2_4=  (np.dot(DIRCOSwind ,np.vstack((wiDrag,junk, wiDrag*0.)))).T #[n,3]  [N]

            #Add them together
            wDrag1_3=waDrag1_3+wiDrag1_3 #[N]
            wDrag2_4=waDrag2_4+wiDrag2_4 #[N]
            wDrag=waDrag+wiDrag #[N]

            wl_idx=np.nonzero(wDrag)[0] #indices of the pile-leg nodes where loading is applied--

            if VPFlag and pileidx:  #Need to account for the cos
               #Forces on legs 1 (and 3 though sign of Fz reversed)
                wDrag1_3[pileidx]=wDrag2_4[pileidx]

            n_pillegLds=wl_idx.size
            n_loads=n_pillegLds*nlegs #Total number of wave load nodes

            pilleg_ndsfrc=np.zeros([n_loads,7])
            nNodespile=pileidx.size  #number of nodes in 1 pile
            nNodesleg=legidx.size  #number of nodes in 1 leg

            for ii in range(0,nlegs): #Cycle through legs
                idx0=nNodespile*ii  #start index for pile IDs
                idx1=idx0+nNodespile #stop index for pile IDs
                idx2=nNodesleg*ii   #start index for leg IDs
                idx3=idx2+nNodesleg  #stop index for leg IDs
                nd_ids=np.vstack((self.pilendIDs[idx0:idx1],self.legndIDs[idx2:idx3]))[wl_idx]
                if np.mod(ii,2)==0:
                    lds=wDrag2_4[wl_idx,:]
                elif ii==1:
                    lds=np.hstack((wDrag1_3[wl_idx,0:2],-wDrag1_3[wl_idx,2].reshape(-1,1)))
                else:
                    lds=wDrag1_3[wl_idx,:]

                idx0=n_pillegLds*ii #start index in pilleg_ndsfrc
                idx1=idx0+n_pillegLds  #stop index in pilleg_ndsfrc
                pilleg_ndsfrc[idx0:idx1,:-3]=np.hstack((nd_ids,lds))

                #Store wave loads
                self.Loadouts.wdrag1_3=wDrag1_3
                self.Loadouts.wdrag2_4=wDrag2_4

        else: #3legged jacket in progress
            #TO DO THIS CASE
            sys.exit("nlegs <>4 not implemented yet for loading")

        #-----Need to add hydrostatic loading -BUOYANCY FORCE
        #IT is a distributed force along the non-flooded members
        #Still TO DO

        #________________________________TOWER__________________________________#
        #Now get the values of the loads at the nodes of Tower

        junk=(np.roll(twrZs,-1)-np.roll(twrZs,1))[1:-1]/2.
        deltaz=np.hstack(((twrZs[1]-twrZs[0])/2.,junk,(twrZs[-1]-twrZs[-2])/2.))#these are the appropriate deltazs

        #just wind loading for tower but wtrload perhaps in the future for tripods
        junk=(np.sqrt(self.towerWindLoads.Px**2+self.towerWindLoads.Py**2)*deltaz).reshape([-1,1]) #[N] forces

        #decompose along local x,y and add z component
        junk=np.hstack((junk,np.zeros([junk.size,2]))).T
        self.Loadouts.twr_dragf=np.dot(DIRCOSwind , junk)    #*np.sin(wind_dict['psi']), junk*0.])

        #Tower Loads for Frame3DD
        n_twrlds=(twrndIDs.shape[0]-TwrRigidTop)*(self.Loadouts.twr_dragf.any()) #distributed loads along tower+RNA node load
        twr_ndsfrc=np.zeros([n_twrlds,7])
        twr_ndsfrc[0:n_twrlds,:-3]=np.hstack((twrndIDs[0:len(twrndIDs)-TwrRigidTop].reshape([-1,1]),self.Loadouts.twr_dragf.T))

        #____________ADD CONCENTRATED RNA FORCES________________________________#
        #First account for moment transfer in global coordinate system as if yaw=0
        RNAload=np.copy(self.RNA_F.reshape([2,3]).T)#RNAload: 1columns forces, 2nd column moments

        #Store yaw-rotated forces and moments at the hub still  [3,2]
        self.Loadouts.RNAload=np.dot(DIRCOSwind,RNAload)

        Deltax=self.RNAinputs.Thoff[0]-self.RNAinputs.CMoff[0]
        Deltay=self.RNAinputs.Thoff[1]-self.RNAinputs.CMoff[1]
        Deltaz=self.RNAinputs.Thoff[2]-self.RNAinputs.CMoff[2]

        if  not(TwrRigidTop):
            Deltax=self.RNAinputs.Thoff[0]
            Deltay=self.RNAinputs.Thoff[1]
            Deltaz=self.RNAinputs.Thoff[2]

        #Rotor Loads - no weight yet
        RNAload[0,1] += -RNAload[1,0]*Deltaz + RNAload[2,0]*Deltay #Mxx=-Fy*Deltaz +Fz*deltay
        RNAload[1,1] +=  RNAload[0,0]*Deltaz - RNAload[2,0]*Deltax  #Myy= Fx*deltaz-Fz*deltax
        RNAload[2,1] += -RNAload[0,0]*Deltay + RNAload[1,0]*Deltax #Mzz=-Fx*Deltay +Fy*deltax

        #Then rotate them in the global coordinate system for PYFRAME to account for yaw
        RNAload=np.dot(DIRCOSwind,RNAload) #Gravity is already accounted for by Frame3DD for concentrated masses: Jacket.Twr.RNAmass*aux['g_z'],np.zeros(3)))  self.RNA_F.reshape([2,3]).T
        if not(TwrRigidTop):
            twr_ndsfrc[-1,1:] += RNAload.T.flatten()
        else:
            twr_ndsfrc = np.vstack(( twr_ndsfrc,np.hstack((twrndIDs[-1],RNAload.T.flatten())) ))

        # If we apply this load at tower-top and not tower-top+CMzoff we need to account for different DeltaZ
##        if  not(TwrRigidTop):
##            RNAload[0,1] -= RNAload[1,0]*ThOffset_z  #*CMzoff #Mxx
##            RNAload[1,1] += RNAload[0,0]*CMzoff #Myy
##            twr_ndsfrc[-1,1:] += RNAload.T.flatten()
##        else: #Put forces at the RNA.CM location
##            RNAload[0,1] -= RNAload[1,0]*ThOffset_z  #*CMzoff #Mxx
##            RNAload[1,1] += RNAload[0,0]*CMzoff #Myy
##
##            twr_ndsfrc[-1,:] += np.hstack((twrndIDs[-1],RNAload.T.flatten()))

        #STACK ALLOF THEM TOGETHER
        self.Loadouts.nds_frc=np.vstack((pilleg_ndsfrc, twr_ndsfrc))  #Concentrated loads
Ejemplo n.º 12
0
    def execute(self):

        rho = self.rho
        U = self.U
        U0 = self.U0
        d = self.d
        zrel = self.z - self.wlevel
        mu = self.mu
        beta = self.beta
        beta0 = self.beta0

        # dynamic pressure
        q = 0.5 * rho * U**2
        q0 = 0.5 * rho * U0**2

        # Reynolds number and drag
        if self.cd_usr:
            cd = self.cd_usr * np.ones_like(self.d)
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho * U * d / mu
            cd, dcd_dRe = cylinderDrag(Re)

        d = self.d
        mu = self.mu
        beta = self.beta

        # inertial and drag forces
        Fi = rho * self.cm * math.pi / 4.0 * d**2 * self.A  # Morrison's equation
        Fd = q * cd * d
        Fp = Fi + Fd

        #FORCES [N/m] AT z=0 m
        idx0 = np.abs(
            zrel).argmin()  # closest index to z=0, used to find d at z=0
        d0 = d[idx0]  # initialize
        cd0 = cd[idx0]  # initialize
        if (zrel[idx0] < 0.) and (idx0 < (zrel.size - 1)):  # point below water
            d0 = np.mean(d[idx0:idx0 + 2])
            cd0 = np.mean(cd[idx0:idx0 + 2])
        elif (zrel[idx0] > 0.) and (idx0 > 0):  # point above water
            d0 = np.mean(d[idx0 - 1:idx0 + 1])
            cd0 = np.mean(cd[idx0 - 1:idx0 + 1])
        Fi0 = rho * self.cm * math.pi / 4.0 * d0**2 * self.A0  # Morrison's equation
        Fd0 = q0 * cd0 * d0
        Fp0 = Fi0 + Fd0

        # components of distributed loads
        Px = Fp * cosd(beta)
        Py = Fp * sind(beta)
        Pz = 0. * Fp

        Px0 = Fp0 * cosd(beta0)
        Py0 = Fp0 * sind(beta0)
        Pz0 = 0. * Fp0

        #Store qties at z=0 MSL
        self.waveLoads.Px0 = Px0
        self.waveLoads.Py0 = Py0
        self.waveLoads.Pz0 = Pz0
        self.waveLoads.q0 = q0
        self.waveLoads.beta0 = beta0

        # pack data
        self.waveLoads.Px = Px
        self.waveLoads.Py = Py
        self.waveLoads.Pz = Pz
        self.waveLoads.qdyn = q
        self.waveLoads.z = self.z
        self.waveLoads.beta = beta
        self.waveLoads.d = d

        # derivatives
        self.dq_dU = rho * U
        const = (self.dq_dU * cd + q * dcd_dRe * rho * d / mu) * d
        self.dPx_dU = const * cosd(beta)
        self.dPy_dU = const * sind(beta)

        const = (cd + dcd_dRe *
                 Re) * q + rho * self.cm * math.pi / 4.0 * 2 * d * self.A
        self.dPx_dd = const * cosd(beta)
        self.dPy_dd = const * sind(beta)

        const = rho * self.cm * math.pi / 4.0 * d**2
        self.dPx_dA = const * cosd(beta)
        self.dPy_dA = const * sind(beta)
Ejemplo n.º 13
0
    def provideJ(self):

        J = np.array([[cosd(self.precone), -self.Rtip*sind(self.precone)*pi/180.0]])

        return J
Ejemplo n.º 14
0
    def solve_nonlinear(self, params, unknowns, resids):

        #wlevel = params['wlevel']
        #if wlevel > 0.0: wlevel *= -1.0
        
        rho = params['rho']
        U = params['U']
        #U0 = params['U0']
        d = params['d']
        #zrel= params['z']-wlevel
        mu = params['mu']
        beta = params['beta']
        #beta0 = params['beta0']

        # dynamic pressure
        q = 0.5*rho*U**2
        #q0= 0.5*rho*U0**2

        # Reynolds number and drag
        if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)
        else:
            cd = params['cd_usr']*np.ones_like(d)
            Re = 1.0
            dcd_dRe = 0.0

        # inertial and drag forces
        Fi = rho*params['cm']*math.pi/4.0*d**2*params['A']  # Morrison's equation
        Fd = q*cd*d
        Fp = Fi + Fd

        # components of distributed loads
        Px = Fp*cosd(beta)
        Py = Fp*sind(beta)
        Pz = 0.*Fp

        #FORCES [N/m] AT z=0 m
        #idx0 = np.abs(zrel).argmin()  # closest index to z=0, used to find d at z=0
        #d0 = d[idx0]  # initialize
        #cd0 = cd[idx0]  # initialize
        #if (zrel[idx0]<0.) and (idx0< (zrel.size-1)):       # point below water
        #    d0 = np.mean(d[idx0:idx0+2])
        #    cd0 = np.mean(cd[idx0:idx0+2])
        #elif (zrel[idx0]>0.) and (idx0>0):     # point above water
        #    d0 = np.mean(d[idx0-1:idx0+1])
        #    cd0 = np.mean(cd[idx0-1:idx0+1])
        #Fi0 = rho*params['cm']*math.pi/4.0*d0**2*params['A0']  # Morrison's equation
        #Fd0 = q0*cd0*d0
        #Fp0 = Fi0 + Fd0

        #Px0 = Fp0*cosd(beta0)
        #Py0 = Fp0*sind(beta0)
        #Pz0 = 0.*Fp0

        #Store qties at z=0 MSL
        #unknowns['waveLoads_Px0'] = Px0
        #unknowns['waveLoads_Py0'] = Py0
        #unknowns['waveLoads_Pz0'] = Pz0
        #unknowns['waveLoads_qdyn0'] = q0
        #unknowns['waveLoads_beta0'] = beta0

        # pack data
        unknowns['waveLoads_Px'] = Px
        unknowns['waveLoads_Py'] = Py
        unknowns['waveLoads_Pz'] = Pz
        unknowns['waveLoads_qdyn'] = q
        unknowns['waveLoads_pt'] = q + params['p']
        unknowns['waveLoads_z'] = params['z']
        unknowns['waveLoads_beta'] = beta
        unknowns['waveLoads_d'] = d
Ejemplo n.º 15
0
    def execute(self):

        self.R = self.Rtip * cosd(self.precone) + self.precurveTip * sind(
            self.precone)
Ejemplo n.º 16
0
    def linearize(self, params, unknowns, resids):

        #wlevel = params['wlevel']
        #if wlevel > 0.0: wlevel *= -1.0
        
        rho = params['rho']
        U = params['U']
        #U0 = params['U0']
        d = params['d']
        #zrel= params['z']-wlevel
        mu = params['mu']
        beta = params['beta']
        #beta0 = params['beta0']

        # dynamic pressure
        q = 0.5*rho*U**2
        #q0= 0.5*rho*U0**2

        # Reynolds number and drag
        if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
            cd = params['cd_usr']*np.ones_like(d)
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)

        # derivatives
        dq_dU = rho*U
        const = (dq_dU*cd + q*dcd_dRe*rho*d/mu)*d
        dPx_dU = const*cosd(beta)
        dPy_dU = const*sind(beta)

        const = (cd + dcd_dRe*Re)*q + rho*params['cm']*math.pi/4.0*2*d*params['A']
        dPx_dd = const*cosd(beta)
        dPy_dd = const*sind(beta)

        const = rho*params['cm']*math.pi/4.0*d**2
        dPx_dA = const*cosd(beta)
        dPy_dA = const*sind(beta)

        n = len(params['z'])

        zeron = np.zeros((n, n))


        J = {}
        J['waveLoads.Px', 'U'] = np.diag(dPx_dU)
        J['waveLoads.Px', 'A'] = np.diag(dPx_dA)
        J['waveLoads.Px', 'z'] = zeron
        J['waveLoads.Px', 'd'] = np.diag(dPx_dd)
        J['waveLoads.Px', 'p'] = zeron

        J['waveLoads.Py', 'U'] = np.diag(dPy_dU)
        J['waveLoads.Py', 'A'] = np.diag(dPy_dA)
        J['waveLoads.Py', 'z'] = zeron
        J['waveLoads.Py', 'd'] = np.diag(dPy_dd)
        J['waveLoads.Py', 'p'] = zeron

        J['waveLoads.Pz', 'U'] = zeron
        J['waveLoads.Pz', 'A'] = zeron
        J['waveLoads.Pz', 'z'] = zeron
        J['waveLoads.Pz', 'd'] = zeron
        J['waveLoads.Pz', 'p'] = zeron

        J['waveLoads.qdyn', 'U'] = np.diag(dq_dU)
        J['waveLoads.qdyn', 'A'] = zeron
        J['waveLoads.qdyn', 'z'] = zeron
        J['waveLoads.qdyn', 'd'] = zeron
        J['waveLoads.qdyn', 'p'] = zeron

        J['waveLoads.pt', 'U'] = np.diag(dq_dU)
        J['waveLoads.pt', 'A'] = zeron
        J['waveLoads.pt', 'z'] = zeron
        J['waveLoads.pt', 'd'] = zeron
        J['waveLoads.pt', 'p'] = 1.0

        J['waveLoads.z', 'U'] = zeron
        J['waveLoads.z', 'A'] = zeron
        J['waveLoads.z', 'z'] = np.eye(n)
        J['waveLoads.z', 'd'] = zeron
        J['waveLoads.z', 'p'] = zeron

        return J
Ejemplo n.º 17
0
    def execute(self):
        #simplify nomenclature
        psi_wi = self.towerWindLoads.beta[
            0]  #psi is stored in beta already, however for legs and piles it needs to be adjusted for psi
        psi_wa = self.towerWaveLoads.beta[0]
        twrZs = self.towerWindLoads.z
        pillegZs = self.pileLegWaveLoads.z
        pillegDs = self.pileLegWaveLoads.d
        nlegs = self.nlegs
        al_bat3D = self.al_bat3D
        VPFlag = self.VPFlag

        TwrRigidTop = (
            self.RNAinputs.CMoff[2] != 0.
        ) and self.TwrRigidTop  #This makes sure we do not have TwrRigidTop=True with CMzoff=0., no length segment that is.

        pilendIDs = self.pilendIDs
        legndIDs = self.legndIDs
        twrndIDs = self.twrndIDs

        wdepth = self.wdepth

        #COSINE MATRIX FROM LOCAL TO GLOBAL COORDINATE SYSTEMS
        DIRCOSwind = np.array([[cosd(psi_wi), -sind(psi_wi), 0.],
                               [sind(psi_wi), cosd(psi_wi), 0.], [0., 0., 1.]])
        DIRCOSwave = np.array([[cosd(psi_wa), -sind(psi_wa), 0.],
                               [sind(psi_wa), cosd(psi_wa), 0.], [0., 0., 1.]])

        #I need to get the right node IDs to be able to assign forces for Frame3DD

        #Get the values of the loads at the nodes of pile and leg 1
        #for the other legs, the wdrag is going to be the same

        if nlegs == 4:  #Diagonal loading condition ONLY for the time being
            pileidx = np.array([])  #Initialize in case empty piles
            if pilendIDs.size:
                pileidx = pilendIDs[
                    0:pilendIDs.size /
                    nlegs]  #np.arange(Pilemems[0,0],Pilemems[-1,1]/nlegs+1)-1   #indices of pile 1

            legidx = legndIDs[
                0:legndIDs.size /
                nlegs]  #legidx=np.arange(Legmems[0,0],Legmems[-1,1]/nlegs+1)-1 #indices of leg 1

            deltaz = (
                (np.roll(pillegZs, -1) - pillegZs) / 2
            )[0:
              -1]  #these are the appropriate 1/2 deltazs for the entire pile-leg assembly
            deltaz = np.hstack(
                (deltaz[0], (np.roll(deltaz, -1) + deltaz)[0:-1], deltaz[-1])
            )  #This is the actual DeltaZ to be assigned at each node starting from the 2nd and ending at the one before last

            #Correct the delta z for the node just below water to avoid jumps in loading - use refined mesh however
            #idx_bw=np.nonzero(pillegZs<= wdepth)[0][-1] #CJB- Original code. Modified line below
            idx_bw = np.nonzero(pillegZs <= 0)[0][
                -1]  #CJBe THe MSL is now at z=0, not z=wdepth
            #Also Attempt at using load at z=0
            ###Px0=self.pileLegWaveLoads.Px_i0overd2*pillegDs[idx_bw]**2+self.pileLegWaveLoads.Px_d0overd*pillegDs[idx_bw]
            ###Py0=self.pileLegWaveLoads.Py_i0overd2*pillegDs[idx_bw]**2+self.pileLegWaveLoads.Py_d0overd*pillegDs[idx_bw]
            Px0 = self.pileLegWaveLoads.Px0
            Py0 = self.pileLegWaveLoads.Py0
            #deltaz0=(wdepth-pillegZs[idx_bw]) #CJB- Original code. Modified line below
            deltaz0 = np.abs(0 - pillegZs[idx_bw])  #CJBe
            #if (wdepth-pillegZs[idx_bw])> deltaz[idx_bw]/2.:  #point with its deltaz entriely below surface #CJB- Original code. Modified line below
            if np.abs(0 - pillegZs[idx_bw]) > np.abs(
                    deltaz[idx_bw] / 2.):  #CJBe Remove wdepth
                deltaz0 -= deltaz[
                    idx_bw] / 2.  #note deltaz0 before deltaz as deltaz gets modified
                #deltaz[idx_bw]=deltaz[idx_bw]/2. -(pillegZs[idx_bw]-wdepth)
            else:
                deltaz[idx_bw] = deltaz[idx_bw] / 2.

            waDrag0 = np.sqrt(
                Px0**2. + Py0**2.
            ) * deltaz0  #In case add this one to the original wDrag, or alternatively do awhat I do below, increasing Deltaz

            waDrag = np.sqrt(
                self.pileLegWaveLoads.Px**2. + self.pileLegWaveLoads.Py**2.
            ) * deltaz  #[N] forces from waves, considered normal to the sloping 1 leg.
            waDrag[idx_bw] += waDrag0

            wiDrag = np.sqrt(
                self.pileLegWindLoads.Px**2. + self.pileLegWindLoads.Py**2.
            ) * deltaz * (
                np.cos(al_bat3D)
            )**2  #[N] forces from wind normal to the sloping 1 leg. Wind is horizontal, that's why cos^2

            #Forces on legs 1 (and 3 though sign of Fz reversed)
            junk = np.zeros(waDrag.size)
            waDrag1_3 = (
                np.dot(
                    DIRCOSwave,
                    np.vstack((waDrag * np.cos(al_bat3D), junk,
                               waDrag * np.sin(al_bat3D))))
            ).T  #[n,3] [N] This is an approx for air drag, as it is not normal to the leg to begin with, but it makes it easier
            wiDrag1_3 = (np.dot(
                DIRCOSwind,
                np.vstack((wiDrag * np.cos(al_bat3D), junk,
                           wiDrag * np.sin(al_bat3D))))).T  #[n,3] [N]

            #Forces on legs 2 (and 4), it is as if they were vertical
            waDrag2_4 = (np.dot(DIRCOSwave,
                                np.vstack((waDrag, junk,
                                           waDrag * 0.)))).T  #[n,3]  [N]
            wiDrag2_4 = (np.dot(DIRCOSwind,
                                np.vstack((wiDrag, junk,
                                           wiDrag * 0.)))).T  #[n,3]  [N]

            #Add them together
            wDrag1_3 = waDrag1_3 + wiDrag1_3  #[N]
            wDrag2_4 = waDrag2_4 + wiDrag2_4  #[N]
            wDrag = waDrag + wiDrag  #[N]

            wl_idx = np.nonzero(wDrag)[
                0]  #indices of the pile-leg nodes where loading is applied--

            if VPFlag and pileidx:  #Need to account for the cos
                #Forces on legs 1 (and 3 though sign of Fz reversed)
                wDrag1_3[pileidx] = wDrag2_4[pileidx]

            n_pillegLds = wl_idx.size
            n_loads = n_pillegLds * nlegs  #Total number of wave load nodes

            pilleg_ndsfrc = np.zeros([n_loads, 7])
            nNodespile = pileidx.size  #number of nodes in 1 pile
            nNodesleg = legidx.size  #number of nodes in 1 leg

            for ii in range(0, nlegs):  #Cycle through legs
                idx0 = nNodespile * ii  #start index for pile IDs
                idx1 = idx0 + nNodespile  #stop index for pile IDs
                idx2 = nNodesleg * ii  #start index for leg IDs
                idx3 = idx2 + nNodesleg  #stop index for leg IDs
                nd_ids = np.vstack((self.pilendIDs[idx0:idx1],
                                    self.legndIDs[idx2:idx3]))[wl_idx]
                if np.mod(ii, 2) == 0:
                    lds = wDrag2_4[wl_idx, :]
                elif ii == 1:
                    lds = np.hstack(
                        (wDrag1_3[wl_idx,
                                  0:2], -wDrag1_3[wl_idx, 2].reshape(-1, 1)))
                else:
                    lds = wDrag1_3[wl_idx, :]

                idx0 = n_pillegLds * ii  #start index in pilleg_ndsfrc
                idx1 = idx0 + n_pillegLds  #stop index in pilleg_ndsfrc
                pilleg_ndsfrc[idx0:idx1, :-3] = np.hstack((nd_ids, lds))

                #Store wave loads
                self.Loadouts.wdrag1_3 = wDrag1_3
                self.Loadouts.wdrag2_4 = wDrag2_4

        else:  #3legged jacket in progress
            #TO DO THIS CASE
            sys.exit("nlegs <>4 not implemented yet for loading")

        #-----Need to add hydrostatic loading -BUOYANCY FORCE
        #IT is a distributed force along the non-flooded members
        #Still TO DO

        #________________________________TOWER__________________________________#
        #Now get the values of the loads at the nodes of Tower

        junk = (np.roll(twrZs, -1) - np.roll(twrZs, 1))[1:-1] / 2.
        deltaz = np.hstack(
            ((twrZs[1] - twrZs[0]) / 2., junk,
             (twrZs[-1] - twrZs[-2]) / 2.))  #these are the appropriate deltazs

        #just wind loading for tower but wtrload perhaps in the future for tripods
        junk = (
            np.sqrt(self.towerWindLoads.Px**2 + self.towerWindLoads.Py**2) *
            deltaz).reshape([-1, 1])  #[N] forces

        #decompose along local x,y and add z component
        junk = np.hstack((junk, np.zeros([junk.size, 2]))).T
        self.Loadouts.twr_dragf = np.dot(
            DIRCOSwind, junk)  #*np.sin(wind_dict['psi']), junk*0.])

        #Tower Loads for Frame3DD
        n_twrlds = (twrndIDs.shape[0] - TwrRigidTop) * (
            self.Loadouts.twr_dragf.any()
        )  #distributed loads along tower+RNA node load
        twr_ndsfrc = np.zeros([n_twrlds, 7])
        twr_ndsfrc[0:n_twrlds, :-3] = np.hstack(
            (twrndIDs[0:len(twrndIDs) - TwrRigidTop].reshape([-1, 1]),
             self.Loadouts.twr_dragf.T))

        #____________ADD CONCENTRATED RNA FORCES________________________________#
        #First account for moment transfer in global coordinate system as if yaw=0
        RNAload = np.copy(self.RNA_F.reshape(
            [2, 3]).T)  #RNAload: 1columns forces, 2nd column moments

        #Store yaw-rotated forces and moments at the hub still  [3,2]
        self.Loadouts.RNAload = np.dot(DIRCOSwind, RNAload)

        Deltax = self.RNAinputs.Thoff[0] - self.RNAinputs.CMoff[0]
        Deltay = self.RNAinputs.Thoff[1] - self.RNAinputs.CMoff[1]
        Deltaz = self.RNAinputs.Thoff[2] - self.RNAinputs.CMoff[2]

        if not (TwrRigidTop):
            Deltax = self.RNAinputs.Thoff[0]
            Deltay = self.RNAinputs.Thoff[1]
            Deltaz = self.RNAinputs.Thoff[2]

        #Rotor Loads - no weight yet
        RNAload[0, 1] += -RNAload[1, 0] * Deltaz + RNAload[
            2, 0] * Deltay  #Mxx=-Fy*Deltaz +Fz*deltay
        RNAload[1, 1] += RNAload[0, 0] * Deltaz - RNAload[
            2, 0] * Deltax  #Myy= Fx*deltaz-Fz*deltax
        RNAload[2, 1] += -RNAload[0, 0] * Deltay + RNAload[
            1, 0] * Deltax  #Mzz=-Fx*Deltay +Fy*deltax

        #Then rotate them in the global coordinate system for PYFRAME to account for yaw
        RNAload = np.dot(
            DIRCOSwind, RNAload
        )  #Gravity is already accounted for by Frame3DD for concentrated masses: Jacket.Twr.RNAmass*aux['g_z'],np.zeros(3)))  self.RNA_F.reshape([2,3]).T
        if not (TwrRigidTop):
            twr_ndsfrc[-1, 1:] += RNAload.T.flatten()
        else:
            twr_ndsfrc = np.vstack(
                (twr_ndsfrc, np.hstack((twrndIDs[-1], RNAload.T.flatten()))))

        # If we apply this load at tower-top and not tower-top+CMzoff we need to account for different DeltaZ


##        if  not(TwrRigidTop):
##            RNAload[0,1] -= RNAload[1,0]*ThOffset_z  #*CMzoff #Mxx
##            RNAload[1,1] += RNAload[0,0]*CMzoff #Myy
##            twr_ndsfrc[-1,1:] += RNAload.T.flatten()
##        else: #Put forces at the RNA.CM location
##            RNAload[0,1] -= RNAload[1,0]*ThOffset_z  #*CMzoff #Mxx
##            RNAload[1,1] += RNAload[0,0]*CMzoff #Myy
##
##            twr_ndsfrc[-1,:] += np.hstack((twrndIDs[-1],RNAload.T.flatten()))

#STACK ALLOF THEM TOGETHER
        self.Loadouts.nds_frc = np.vstack(
            (pilleg_ndsfrc, twr_ndsfrc))  #Concentrated loads
Ejemplo n.º 18
0
    def linearize(self, params, unknowns, resids):

        #wlevel = params['wlevel']
        #if wlevel > 0.0: wlevel *= -1.0
        
        rho = params['rho']
        U = params['U']
        #U0 = params['U0']
        d = params['d']
        #zrel= params['z']-wlevel
        mu = params['mu']
        beta = params['beta']
        #beta0 = params['beta0']

        # dynamic pressure
        q = 0.5*rho*U**2
        #q0= 0.5*rho*U0**2

        # Reynolds number and drag
        if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
            cd = params['cd_usr']*np.ones_like(d)
            Re = 1.0
            dcd_dRe = 0.0
        else:
            Re = rho*U*d/mu
            cd, dcd_dRe = cylinderDrag(Re)

        # derivatives
        dq_dU = rho*U
        const = (dq_dU*cd + q*dcd_dRe*rho*d/mu)*d
        dPx_dU = const*cosd(beta)
        dPy_dU = const*sind(beta)

        const = (cd + dcd_dRe*Re)*q + rho*params['cm']*math.pi/4.0*2*d*params['A']
        dPx_dd = const*cosd(beta)
        dPy_dd = const*sind(beta)

        const = rho*params['cm']*math.pi/4.0*d**2
        dPx_dA = const*cosd(beta)
        dPy_dA = const*sind(beta)

        n = len(params['z'])

        zeron = np.zeros((n, n))


        J = {}
        J['waveLoads.Px', 'U'] = np.diag(dPx_dU)
        J['waveLoads.Px', 'A'] = np.diag(dPx_dA)
        J['waveLoads.Px', 'z'] = zeron
        J['waveLoads.Px', 'd'] = np.diag(dPx_dd)
        J['waveLoads.Px', 'p'] = zeron

        J['waveLoads.Py', 'U'] = np.diag(dPy_dU)
        J['waveLoads.Py', 'A'] = np.diag(dPy_dA)
        J['waveLoads.Py', 'z'] = zeron
        J['waveLoads.Py', 'd'] = np.diag(dPy_dd)
        J['waveLoads.Py', 'p'] = zeron

        J['waveLoads.Pz', 'U'] = zeron
        J['waveLoads.Pz', 'A'] = zeron
        J['waveLoads.Pz', 'z'] = zeron
        J['waveLoads.Pz', 'd'] = zeron
        J['waveLoads.Pz', 'p'] = zeron

        J['waveLoads.qdyn', 'U'] = np.diag(dq_dU)
        J['waveLoads.qdyn', 'A'] = zeron
        J['waveLoads.qdyn', 'z'] = zeron
        J['waveLoads.qdyn', 'd'] = zeron
        J['waveLoads.qdyn', 'p'] = zeron

        J['waveLoads.pt', 'U'] = np.diag(dq_dU)
        J['waveLoads.pt', 'A'] = zeron
        J['waveLoads.pt', 'z'] = zeron
        J['waveLoads.pt', 'd'] = zeron
        J['waveLoads.pt', 'p'] = 1.0

        J['waveLoads.z', 'U'] = zeron
        J['waveLoads.z', 'A'] = zeron
        J['waveLoads.z', 'z'] = np.eye(n)
        J['waveLoads.z', 'd'] = zeron
        J['waveLoads.z', 'p'] = zeron

        return J
Ejemplo n.º 19
0
    def solve_nonlinear(self, params, unknowns, resids):

        #wlevel = params['wlevel']
        #if wlevel > 0.0: wlevel *= -1.0

        rho = params['rho']
        U = params['U']
        #U0 = params['U0']
        d = params['d']
        #zrel= params['z']-wlevel
        mu = params['mu']
        beta = params['beta']
        #beta0 = params['beta0']

        if not (params['rho'] == 0. or all(params['U'] == 0.) or params['mu'] == 0.):

            # dynamic pressure
            q = 0.5*rho*U**2
            #q0= 0.5*rho*U0**2

            # Reynolds number and drag
            if params['cd_usr'] in [np.inf, -np.inf, None, np.nan]:
                Re = rho*U*d/mu
                cd, dcd_dRe = cylinderDrag(Re)
            else:
                cd = params['cd_usr']*np.ones_like(d)
                Re = 1.0
                dcd_dRe = 0.0

            # inertial and drag forces
            Fi = rho*params['cm']*math.pi/4.0*d**2*params['A']  # Morrison's equation
            Fd = q*cd*d
            Fp = Fi + Fd

            # components of distributed loads
            Px = Fp*cosd(beta)
            Py = Fp*sind(beta)
            Pz = 0.*Fp

            #FORCES [N/m] AT z=0 m
            #idx0 = np.abs(zrel).argmin()  # closest index to z=0, used to find d at z=0
            #d0 = d[idx0]  # initialize
            #cd0 = cd[idx0]  # initialize
            #if (zrel[idx0]<0.) and (idx0< (zrel.size-1)):       # point below water
            #    d0 = np.mean(d[idx0:idx0+2])
            #    cd0 = np.mean(cd[idx0:idx0+2])
            #elif (zrel[idx0]>0.) and (idx0>0):     # point above water
            #    d0 = np.mean(d[idx0-1:idx0+1])
            #    cd0 = np.mean(cd[idx0-1:idx0+1])
            #Fi0 = rho*params['cm']*math.pi/4.0*d0**2*params['A0']  # Morrison's equation
            #Fd0 = q0*cd0*d0
            #Fp0 = Fi0 + Fd0

            #Px0 = Fp0*cosd(beta0)
            #Py0 = Fp0*sind(beta0)
            #Pz0 = 0.*Fp0

            #Store qties at z=0 MSL
            #unknowns['waveLoads_Px0'] = Px0
            #unknowns['waveLoads_Py0'] = Py0
            #unknowns['waveLoads_Pz0'] = Pz0
            #unknowns['waveLoads_qdyn0'] = q0
            #unknowns['waveLoads_beta0'] = beta0

            # pack data
            unknowns['waveLoads_Px'] = Px
            unknowns['waveLoads_Py'] = Py
            unknowns['waveLoads_Pz'] = Pz
            unknowns['waveLoads_qdyn'] = q
            unknowns['waveLoads_pt'] = q + params['p']
            unknowns['waveLoads_beta'] = beta

        unknowns['waveLoads_d'] = d
        unknowns['waveLoads_z'] = params['z']