def getFEMvals(u,xiArray,verbose=0): """ for convenience, hide steps for generating finite element solution at physical points corresponding to reference points held in xiArray returns array that's nelem x npointloc """ nelems = u.femSpace.elementMaps.mesh.nElements_global ndofs = u.femSpace.referenceFiniteElement.localFunctionSpace.dim nploc = xiArray.shape[0] bvals = numpy.zeros((nelems,nploc,ndofs),'d') uvals = numpy.zeros((nelems,nploc),'d') u.femSpace.getBasisValues(xiArray,bvals) for eN in range(nelems): for k in range(nploc): for j in range(ndofs): J = u.femSpace.dofMap.l2g[eN,j] uvals[eN,k] += bvals[eN,k,j]*u.dof[J] logEvent("""getFemValues eN=%d xiArray[%d]= %s jloc=%d J=%d u.dof[%d]= %g uvals[%d,%d]= %g """ % (eN,k,xiArray[k],j,J,J,u.dof[J],eN,k,uvals[eN,k]),level=3) #end verbose #end j #end k #end eN return uvals
def __init__(self,period,waveHeight,mwl,depth,g,waveDir,wavelength=None,waveType="Linear",Ycoeff = None, Bcoeff =None, meanVelocity = 0.,phi0 = 0.): self.knownWaveTypes = ["Linear","Fenton","userDefined"] self.waveType = waveType self.g = g self.gAbs = sqrt(sum(g * g)) self.waveDir = waveDir/sqrt(sum(waveDir * waveDir)) self.phi0=phi0 if self.waveType not in self.knownWaveTypes: logEvent("Wrong wavetype given: Valid wavetypes are %s" %(self.knownWaveTypes), level=0) self.dircheck = abs(sum(g * waveDir)) #print self.dircheck if self.dircheck > 1e-6: logEvent("Wave direction is not perpendicular to gravity vector. Check input",level=0) self.period = period self.waveHeight = waveHeight self.mwl = mwl self.depth = depth self.omega = 2.0*pi/period if self.waveType is "Linear": self.k = dispersion(w=self.omega,d=self.depth,g=self.gAbs) self.wavelength = 2.0*pi/self.k else: try: self.k = 2.0*pi/wavelength self.wavelength=wavelength except: pr.logEvent("Wavelenght is not defined for nonlinear waves. Enter wavelength in class arguments") self.kDir = self.k * self.waveDir self.amplitude = 0.5*self.waveHeight self.meanVelocity = meanVelocity self.vDir = self.g/self.gAbs if (Ycoeff is None) or (Bcoeff is None): if self.waveType is not "Linear": pr.logEvent("Need to define Ycoeff and Bcoeff (free-surface and velocity) for nonlinear waves")
def attachModel(self,model,ar): self.tCount=0 self.model=model self.ar=ar self.nd = model.levelModelList[-1].nSpace_global self.levelPlist=[] self.levelThetalist=[] for m in self.model.levelModelList: p=[] theta=[] if self.nd == 2: for nN in range(m.mesh.nNodes_global): if m.mesh.nodeMaterialTypes[nN] == self.flag: p.append(m.u[0].dof[nN]) theta.append((180.0/math.pi)*math.atan2(m.mesh.nodeArray[nN][1]-self.center[1], m.mesh.nodeArray[nN][0]-self.center[0])) elif self.nd == 3: pass else: logEvent("Can't use stress computation for nd = "+`self.nd`) pass self.levelPlist.append(p) self.levelThetalist.append(theta) if self.ar.hdfFile != None: self.ar.hdfFile.createArray("/",'theta',theta) #self.historyP=[] #self.historyP.append(copy.deepcopy(self.levelPlist)) # try: # self.pWindow=Viewers.windowNumber # self.viewP() # except: # pass #self.dataStorage['PressureTheta'] = self.levelThetalist #self.dataStorage['PressureHistory'] = [self.levelPlist] return self
def calculate(self): for m,V in zip(self.model.levelModelList,self.levelVlist): V.flat[:]=0.0 for eN in range(m.mesh.nElements_global): for k in range(m.nQuadraturePoints_element): V[0] += m.q[('u',1)][eN,k]*m.q[('dV_u',0)][eN,k] V[1] += m.q[('u',2)][eN,k]*m.q[('dV_u',0)][eN,k] if self.nd == 3: V[2] += m.q[('u',3)][eN,k]*m.q[('dV_u',0)][eN,k] V/=self.volume # if self.nd ==3: # cfemIntegrals.calculateVelocityVolumeAverage3D(m.mesh.elementBoundaryMaterialTypes, # m.q[('u',1)],#u # m.q[('u',2)],#v # m.q[('u',3)],#w # m.q[('dV_u',0)],#dV # V) # if self.nd == 2: # cfemIntegrals.calculateVelocityVolumeAverage2D(m.mesh.elementBoundaryMaterialTypes, # m.q[('u',1)],#u # m.q[('u',2)],#v # m.q[('dV_u',0)],#dV # V) logEvent("Average Velocity") logEvent(`V`) if self.nd == 2: self.Vfile.write('%21.15e %21.15e \n' % tuple(V)) else: self.Vfile.write('%21.15e %21.15e %21.15e\n' % tuple(V))
def attachModel(self,model,ar): filename = os.path.join(Profiling.logDir,'velocity_average.txt') self.Vfile = open(filename,'w') self.model=model self.ar=ar self.writer = Archiver.XdmfWriter() self.nd = model.levelModelList[-1].nSpace_global m = self.model.levelModelList[-1] #get the volume of the domain self.volume=0.0 for eN in range(m.mesh.nElements_global): for k in range(m.nQuadraturePoints_element): self.volume+=m.q[('dV_u',0)][eN,k] #flagMax = max(m.mesh.elementBoundaryMaterialTypes) #flagMin = min(m.mesh.elementBoundaryMaterialTypes) #assert(flagMin == 0) #assert(flagMax >= 0) self.levelVlist=[] for m in self.model.levelModelList: if self.nd == 2: V = numpy.zeros((2,),'d') elif self.nd == 3: V = numpy.zeros((3,),'d') else: logEvent("Can't use velocity average for nd = "+`self.nd`) V=None self.levelVlist.append(V) # self.historyV=[] # self.historyV.append(copy.deepcopy(self.levelVlist)) # try: # self.velocityWindow=Viewers.windowNumber # self.viewVelocity() # except: # pass return self
def JONSWAP(f, f0, Hs, g, gamma, TMA=False, h=-10): """The wave spectrum from Joint North Sea Wave Observation Project :param f: wave frequency [1/T] :param f0: peak frequency [1/T] :param Hs: significant wave height [L] :param g: gravity [L/T^2] :param gamma: peak enhancement factor [-] """ omega = 2.0 * pi * f omega0 = 2.0 * pi * f0 alpha = 2.0 * pi * 0.0624 * (1.094 - 0.01915 * log(gamma)) / ( 0.23 + 0.0336 * gamma - 0.0185 / (1.9 + gamma)) r = np.exp(-(omega - omega0)**2 / (2 * sigma(omega, omega0)**2 * omega0**2)) tma = 1. if TMA: if (h < 0): logEvent( "Wavetools:py. Provide valid depth definition definition for TMA spectrum" ) logEvent("Wavetools:py. Stopping simulation") exit(1) k = dispersion(2 * pi * f, h) tma = tanh(k * h) * tanh(k * h) / (1. + 2. * k * h / sinh(k * h)) return (tma * alpha * Hs**2 * omega0**4 / omega**5) * np.exp( -(5.0 / 4.0) * (omega0 / omega)**4) * gamma**r
def attachModel(self,model,ar): self.model=model self.ar=ar self.writer = Archiver.XdmfWriter() self.nd = model.levelModelList[-1].nSpace_global m = self.model.levelModelList[-1] flagMax = max(m.mesh.elementBoundaryMaterialTypes) flagMin = min(m.mesh.elementBoundaryMaterialTypes) assert(flagMin == 0) assert(flagMax >= 0) self.nForces=flagMax+1 self.levelFlist=[] for m in self.model.levelModelList: if self.nd == 2: F = numpy.zeros((self.nForces,2),'d') elif self.nd == 3: F = numpy.zeros((self.nForces,3),'d') else: logEvent("Can't use stress computation for nd = "+`self.nd`) F=None self.levelFlist.append(F) self.historyF=[] self.historyF.append(copy.deepcopy(self.levelFlist)) # try: # self.dragWindow=Viewers.windowNumber # self.viewForce() # except: # pass return self
def __init__(self,baseFlags="zen",nbase=0,verbose=0): """ initialize the triangulation object, keep track of what numbering scheme it uses, create a base set of flags for triangulate (e.g., z if using base 0) does not create a Voronoi diagram by default """ self.trirep = [] self.trirep.append(triangleWrappers.new()) self.trirepDefaultInit = [] self.trirepDefaultInit.append(True) self.vorrep = [] self.vorrep.append(triangleWrappers.new()) #don't create a Voronoi diagram by default self.makeVoronoi = False self.vorrepDefaultInit = [] self.vorrepDefaultInit.append(True) assert(nbase in [0,1]) self.nbase = nbase self.baseFlags = baseFlags if self.nbase == 0 and self.baseFlags.find('z') == -1: print """WARNING TriangleMesh base numbering= %d reqires z in baseFlags = %s, adding """ % (self.nbase,self.baseFlags) self.baseFlags += "z" #end if if self.baseFlags.find('v') >= 0: self.makeVoronoi = True if verbose > 0: logEvent("""TriangleBaseMesh nbase=%d baseFlags= %s """ % (self.nbase, self.baseFlags)) #end if #keep track of last set of flags used to generate rep self.lastFlags = None #to make printing out info easier self.infoFormat = """triangulation:
def setOrder(self,k): self.order=k if self.order > len(self.pointsAll): logEvent("WARNING Q_base requested order=%d > max allowed=%d setting order to max" % (self.order, len(self.pointsAll))) self.order= len(self.pointsAll) self.points=self.pointsAll[self.order-1] self.weights=self.weightsAll[self.order-1]
def setOrder(self, k): self.order = k if self.order > len(self.pointsAll): logEvent( "WARNING Q_base requested order=%d > max allowed=%d setting order to max" % (self.order, len(self.pointsAll))) self.order = len(self.pointsAll) self.points = self.pointsAll[self.order - 1] self.weights = self.weightsAll[self.order - 1]
def __init__(self, ghosted_csr_mat, par_bs, par_n, par_N, par_nghost, subdomain2global, blockVecType="simple", pde=None): self.pde = pde p4pyPETSc.Mat.__init__(self) self.ghosted_csr_mat = ghosted_csr_mat self.blockVecType = blockVecType assert self.blockVecType == "simple", "petsc4py wrappers require self.blockVecType=simple" self.create(p4pyPETSc.COMM_WORLD) blockSize = max(1, par_bs) if blockSize >= 1 and blockVecType != "simple": ## \todo fix block aij in ParMat_petsc4py self.setType('baij') self.setSizes([[blockSize * par_n, blockSize * par_N], [blockSize * par_n, blockSize * par_N]], bsize=blockSize) self.setBlockSize(blockSize) self.subdomain2global = subdomain2global #no need to include extra block dofs? else: self.setType('aij') self.setSizes([[par_n * blockSize, par_N * blockSize], [par_n * blockSize, par_N * blockSize]], bsize=1) if blockSize > 1: #have to build in block dofs subdomain2globalTotal = numpy.zeros( (blockSize * subdomain2global.shape[0], ), 'i') for j in range(blockSize): subdomain2globalTotal[ j::blockSize] = subdomain2global * blockSize + j self.subdomain2global = subdomain2globalTotal else: self.subdomain2global = subdomain2global import Comm comm = Comm.get() logEvent( "ParMat_petsc4py comm.rank= %s blockSize = %s par_n= %s par_N=%s par_nghost=%s par_jacobian.getSizes()= %s " % (comm.rank(), blockSize, par_n, par_N, par_nghost, self.getSizes())) self.csr_rep = ghosted_csr_mat.getCSRrepresentation() blockOwned = blockSize * par_n self.csr_rep_owned = ghosted_csr_mat.getSubMatCSRrepresentation( 0, blockOwned) self.petsc_l2g = p4pyPETSc.LGMap() self.petsc_l2g.create(self.subdomain2global) self.colind_global = self.petsc_l2g.apply( self.csr_rep_owned[1]) #prealloc needs global indices self.setPreallocationCSR( [self.csr_rep_owned[0], self.colind_global, self.csr_rep_owned[2]]) self.setUp() self.setLGMap(self.petsc_l2g) self.setFromOptions()
def mult(self, A, x, y): logEvent("Using SparseMatShell in LinearSolver matrix multiply") if self.xGhosted == None: self.xGhosted = self.par_b.duplicate() self.yGhosted = self.par_b.duplicate() self.xGhosted.setArray(x.getArray()) self.xGhosted.ghostUpdateBegin(p4pyPETSc.InsertMode.INSERT,p4pyPETSc.ScatterMode.FORWARD) self.xGhosted.ghostUpdateEnd(p4pyPETSc.InsertMode.INSERT,p4pyPETSc.ScatterMode.FORWARD) self.yGhosted.zeroEntries() self.ghosted_csr_mat.matvec(self.xGhosted.getLocalForm().getArray(),self.yGhosted.getLocalForm().getArray()) y.setArray(self.yGhosted.getArray())
def plotSeries(self): "Plots the timeseries in timeSeries.pdf. If returnPlot is set to True, returns a line object" from matplotlib import pyplot as plt #insert comm fig = plt.figure(1) line = plt.plot(self.time,self.eta) plt.grid() plt.xlabel("Time") plt.ylabel("Elevation") plt.savefig("timeSeries.pdf") logEvent("WaveTools.py: Plotting timeseries in timeSeries.pdf",level=0) plt.close("all") del fig
def plotSeries(self): "Plots the timeseries in timeSeries.pdf. If returnPlot is set to True, returns a line object" from matplotlib import pyplot as plt #insert comm fig = plt.figure(1) line = plt.plot(self.time, self.eta) plt.grid() plt.xlabel("Time") plt.ylabel("Elevation") plt.savefig("timeSeries.pdf") logEvent("WaveTools.py: Plotting timeseries in timeSeries.pdf", level=0) plt.close("all") del fig
def calculate(self): for m,regions,results in zip(self.model.levelModelList,self.elementsInRegion,self.levelNormList): for key in ['L2','L1','LI']: results[key] = 0.0 for region in regions:#go through material types for eN in region[0]: #where returns a tuple for k in range(m.nQuadraturePoints_element): e1 = numpy.sum(numpy.absolute(m.q[('velocity',0)][eN,k,:])) e2 = numpy.inner(m.q[('velocity',0)][eN,k,:],m.q[('velocity',0)][eN,k,:]) ei = numpy.max(numpy.absolute(m.q[('velocity',0)][eN,k,:])) results['L2'] += e2*m.q[('dV_u',0)][eN,k] results['L1'] += e1*m.q[('dV_u',0)][eN,k] results['LI'] = max(results['LI'],ei) logEvent("Velocity Norms in Region %s L2= %s L1= %s LI= %s " % (self.regionIdList,results['L2'],results['L1'],results['LI'])) self.Vfile.write('%21.15e %21.15e %21.15e\n' % (results['L2'],results['L1'],results['LI']))
def mult(self, A, x, y): logEvent("Using SparseMatShell in LinearSolver matrix multiply") if self.xGhosted == None: self.xGhosted = self.par_b.duplicate() self.yGhosted = self.par_b.duplicate() self.xGhosted.setArray(x.getArray()) self.xGhosted.ghostUpdateBegin(p4pyPETSc.InsertMode.INSERT, p4pyPETSc.ScatterMode.FORWARD) self.xGhosted.ghostUpdateEnd(p4pyPETSc.InsertMode.INSERT, p4pyPETSc.ScatterMode.FORWARD) self.yGhosted.zeroEntries() with self.xGhosted.localForm() as xlf, self.yGhosted.localForm( ) as ylf: self.ghosted_csr_mat.matvec(xlf.getArray(), ylf.getArray()) y.setArray(self.yGhosted.getArray())
def reconstruct_window(self, x, y, z, t, Nf, var="eta", ss="x"): "Direct reconstruction of a timeseries" if self.rec_direct == False: logEvent( "WaveTools.py: While attempting direct reconstruction, wrong input for rec_direct found (should be set to True)", level=0) logEvent("Stopping simulation", level=0) exit(1) ai = self.decomp[1] ipeak = np.where(ai == max(ai))[0][0] imax = min(ipeak + Nf / 2, len(ai)) imin = max(0, ipeak - Nf / 2) ai = ai[imin:imax] omega = self.decomp[0][imin:imax] phi = self.decomp[2][imin:imax] ki = dispersion(omega, self.depth, g=self.gAbs) kDir = np.zeros((len(ki), 3), "d") Nf = len(omega) for ii in range(len(ki)): kDir[ii, :] = ki[ii] * self.waveDir[:] if var == "eta": Eta = 0. for ii in range(Nf): Eta += ai[ii] * cos(x * kDir[ii, 0] + y * kDir[ii, 1] + z * kDir[ii, 2] - omega[ii] * t - phi[ii]) return Eta if var == "U": UH = 0. UV = 0. for ii in range(Nf): UH += ai[ii] * omega[ii] * cosh( ki[ii] * (Z(x, y, z) + depth)) * cos( x * kDir[ii, 0] + y * kDir[ii, 1] + z * kDir[ii, 2] - omega[ii] * t + phi[ii]) / sinh(ki[ii] * depth) UV += ai[ii] * omega[ii] * sinh( ki[ii] * (Z(x, y, z) + depth)) * sin( x * kDir[ii, 0] + y * kDir[ii, 1] + z * kDir[ii, 2] - omega[ii] * t + phi[ii]) / sinh(ki[ii] * depth) #waves(period = 1./self.fi[ii], waveHeight = 2.*self.ai[ii],mwl = self.mwl, depth = self.d,g = self.g,waveDir = self.waveDir,wavelength=self.wi[ii], phi0 = self.phi[ii]).u(x,y,z,t) Vcomp = { "x": UH * self.waveDir[0] + UV * self.vDir[0], "y": UH * self.waveDir[1] + UV * self.vDir[1], "z": UH * self.waveDir[2] + UV * self.vDir[2], } return Vcomp[ss]
def calculate(self): #loop through meshes in mesh hiearchy and compute average pressure for each face for m,P,A in zip(self.model.levelModelList,self.levelPlist,self.levelAlist): P.flat[:]=0.0 A.flat[:]=0.0 cfemIntegrals.accumulateExteriorElementPressureIntegrals(m.mesh.elementBoundaryMaterialTypes, m.mesh.exteriorElementBoundariesArray, m.ebqe[('u',0)],#pressure m.ebqe[('dS_u',0)],#dS P, A) for i in range(len(A)):#could do this in a fancier way with numpy if abs(A[i]) > 0.0: P[i] /= A[i] logEvent("Pressure") logEvent(`P`) self.historyP.append(copy.deepcopy(self.levelPlist))
def u(self, x, y, z, t, ss="x"): """x-component of velocity :param x: floating point x coordinate :param z: floating point z coordinate (height above bottom) :param t: time """ UH = 0. UV = 0. ii = 0. if self.waveType is "Linear": UH += self.amplitude * self.omega * cosh( self.k * (self.Z(x, y, z) + self.depth)) * cos( self.phase(x, y, z, t)) / sinh(self.k * self.depth) UV += self.omega * self.amplitude * sinh( self.k * (self.Z(x, y, z) + self.depth)) * sin( self.phase(x, y, z, t)) / sinh(self.k * self.depth) #waves(period = 1./self.fi[ii], waveHeight = 2.*self.ai[ii],mwl = self.mwl, depth = self.d,g = self.g,waveDir = self.waveDir,wavelength=self.wi[ii], phi0 = self.phi[ii]).u(x,y,z,t) Vcomp = { "x": UH * self.waveDir[0] + UV * self.vDir[0], "y": UH * self.waveDir[1] + UV * self.vDir[1], "z": UH * self.waveDir[2] + UV * self.vDir[2], } elif self.waveType is "Fenton": for B in self.Bcoeff: ii += 1 UV += ii * B * sinh( self.k * (self.Z(x, y, z) + self.depth)) * sin( self.phase(x, y, z, t)) / cosh(self.k * self.depth) UH += ii * B * cosh( self.k * (self.Z(x, y, z) + self.depth)) * cos( self.phase(x, y, z, t)) / cosh(self.k * self.depth) #waves(period = 1./self.fi[ii], waveHeight = 2.*self.ai[ii],mwl = self.mwl, depth = self.d,g = self.g,waveDir = self.waveDir,wavelength=self.wi[ii], phi0 = self.phi[ii]).u(x,y,z,t) Vcomp = { "x": UH * self.waveDir[0] + UV * self.vDir[0], "y": UH * self.waveDir[1] + UV * self.vDir[1], "z": UH * self.waveDir[2] + UV * self.vDir[2], } else: logEvent("Check Wave types. Available wave types are %s" % waveType, level=0) exit(1) return Vcomp[ss]
def apply(self,w,nsPre,nsPost,level,b,x): logEvent("Level = "+`level`) if level == len(self.AList)-1: self.smootherList[level].apply(1.0,1,b,x) else: #smooth self.smootherList[level].apply(w,nsPre,b,x) #restrict the defect self.rList[level].matvec(self.smootherList[level].res,self.bList[level+1]) #V-cycle on the error equation self.xList[level+1][:]=0.0 self.apply(w,nsPre,nsPost,level+1,self.bList[level+1],self.xList[level+1]) #self.gpList[level].plot(Gnuplot.Data(self.smootherList[level+1].res,title='residual')) #prolong self.pList[level].matvec(self.xList[level+1],self.vList[level]) #correct x-=self.vList[level] #smooth self.smootherList[level].apply(w,nsPost,b,x) self.resList[level][:]=self.smootherList[level].res
def calculate(self): for m,F in zip(self.model.levelModelList,self.levelFlist): F.flat[:]=0.0 if self.nd ==3: cfemIntegrals.calculateExteriorElementBoundaryStress3D(m.mesh.elementBoundaryMaterialTypes, m.mesh.exteriorElementBoundariesArray, m.mesh.elementBoundaryElementsArray, m.mesh.elementBoundaryLocalElementBoundariesArray, m.ebqe[('u',0)],#pressure m.ebqe[('velocity',1)],#mom_flux_vec_u m.ebqe[('velocity',2)],#mom_flux_vec_v m.ebqe[('velocity',3)],#mom_flux_vec_w m.ebqe[('dS_u',0)],#dS m.ebqe[('n')], F) if self.nd == 2: cfemIntegrals.calculateExteriorElementBoundaryStress2D(m.mesh.elementBoundaryMaterialTypes, m.mesh.exteriorElementBoundariesArray, m.mesh.elementBoundaryElementsArray, m.mesh.elementBoundaryLocalElementBoundariesArray, m.ebqe[('u',0)],#pressure m.ebqe[('velocity',1)],#mom_flux_vec_u m.ebqe[('velocity',2)],#mom_flux_vec_v m.ebqe[('dS_u',0)],#dS m.ebqe[('n')], F) logEvent("Force") logEvent(`F`) Ftot=F[0,:] for ib in range(1,self.nForces): Ftot+=F[ib,:] logEvent("Total force on all boundaries") logEvent(`Ftot`) logEvent("Drag Force " +`self.model.stepController.t_model`+" "+`F[-1,0]`) logEvent("Lift Force " +`self.model.stepController.t_model`+" "+`F[-1,1]`) logEvent("Drag Coefficient " +`self.model.stepController.t_model`+" "+`self.C_fact*F[-1,0]`) logEvent("Lift Coefficient " +`self.model.stepController.t_model`+" "+`self.C_fact*F[-1,1]`) # for ib in range(self.nForces): # self.writeScalarXdmf(self.C_fact*F[ib,0],"Drag Coefficient %i" % (ib,)) # self.writeScalarXdmf(self.C_fact*F[ib,1],"Lift Coefficient %i" % (ib,)) self.historyF.append(copy.deepcopy(self.levelFlist))
def calculate(self): ci = self.ci for m,regions,results in zip(self.model.levelModelList,self.elementsInRegion,self.levelNormList): for key in ['total','L2','L1','LI']: results[key] = 0.0 for region in regions:#go through material types for eN in region[0]: #where returns a tuple for k in range(m.nQuadraturePoints_element): e1 = abs(m.q[('m',ci)][eN,k]) e2 = e1*e1 ei = e1 mtot= m.q[('m',self.ci)][eN,k] results['total']+= mtot*m.q[('dV_u',ci)][eN,k] results['L2'] += e2*m.q[('dV_u',ci)][eN,k] results['L1'] += e1*m.q[('dV_u',ci)][eN,k] results['LI'] = max(results['LI'],ei) if self.regionIdList==None: logEvent("Mass Norms in Domain Total= %s L2= %s L1= %s LI= %s " % (results['total'],results['L2'],results['L1'],results['LI'])) else: logEvent("Mass Norms in Domain %s Total= %s L2= %s L1= %s LI= %s " % (self.regionIdList,results['total'],results['L2'],results['L1'],results['LI'])) self.ofile.write('%21.15e %21.15e %21.15e %21.15e\n' % (results['total'],results['L2'],results['L1'],results['LI']))
def __init__(self, period, waveHeight, mwl, depth, g, waveDir, wavelength=None, waveType="Linear", Ycoeff=None, Bcoeff=None, meanVelocity=0., phi0=0.): self.knownWaveTypes = ["Linear", "Fenton", "userDefined"] self.waveType = waveType self.g = g self.gAbs = sqrt(sum(g * g)) self.waveDir = waveDir / sqrt(sum(waveDir * waveDir)) self.phi0 = phi0 if self.waveType not in self.knownWaveTypes: logEvent("Wrong wavetype given: Valid wavetypes are %s" % (self.knownWaveTypes), level=0) sys.exit(1) self.dircheck = abs(sum(g * waveDir)) #print self.dircheck if self.dircheck > 1e-6: logEvent( "Wave direction is not perpendicular to gravity vector. Check input", level=0) sys.exit(1) self.period = period self.waveHeight = waveHeight self.mwl = mwl self.depth = depth self.omega = 2.0 * pi / period if self.waveType is "Linear": self.k = dispersion(w=self.omega, d=self.depth, g=self.gAbs) self.wavelength = 2.0 * pi / self.k else: try: self.k = 2.0 * pi / wavelength self.wavelength = wavelength except: logEvent( "Wavelenght is not defined for nonlinear waves. Enter wavelength in class arguments", level=0) sys.exit(1) self.kDir = self.k * self.waveDir self.amplitude = 0.5 * self.waveHeight self.meanVelocity = meanVelocity self.vDir = self.g / self.gAbs self.Ycoeff = Ycoeff self.Bcoeff = Bcoeff if (Ycoeff is None) or (Bcoeff is None): if self.waveType is not "Linear": pr.logEvent( "Need to define Ycoeff and Bcoeff (free-surface and velocity) for nonlinear waves", level=0) sys.exit(1)
def __init__(self,ghosted_csr_mat,par_bs,par_n,par_N,par_nghost,subdomain2global,blockVecType="simple",pde=None): self.pde = pde p4pyPETSc.Mat.__init__(self) self.ghosted_csr_mat=ghosted_csr_mat self.blockVecType = blockVecType assert self.blockVecType == "simple", "petsc4py wrappers require self.blockVecType=simple" self.create(p4pyPETSc.COMM_WORLD) blockSize = max(1,par_bs) if blockSize >= 1 and blockVecType != "simple": ## \todo fix block aij in ParMat_petsc4py self.setType('baij') self.setSizes([[blockSize*par_n,blockSize*par_N],[blockSize*par_n,blockSize*par_N]],bsize=blockSize) self.setBlockSize(blockSize) self.subdomain2global = subdomain2global #no need to include extra block dofs? else: self.setType('aij') self.setSizes([[par_n*blockSize,par_N*blockSize],[par_n*blockSize,par_N*blockSize]],bsize=1) if blockSize > 1: #have to build in block dofs subdomain2globalTotal = numpy.zeros((blockSize*subdomain2global.shape[0],),'i') for j in range(blockSize): subdomain2globalTotal[j::blockSize]=subdomain2global*blockSize+j self.subdomain2global=subdomain2globalTotal else: self.subdomain2global=subdomain2global import Comm comm = Comm.get() logEvent("ParMat_petsc4py comm.rank= %s blockSize = %s par_n= %s par_N=%s par_nghost=%s par_jacobian.getSizes()= %s " % (comm.rank(),blockSize,par_n,par_N,par_nghost,self.getSizes())) self.csr_rep = ghosted_csr_mat.getCSRrepresentation() blockOwned = blockSize*par_n self.csr_rep_owned = ghosted_csr_mat.getSubMatCSRrepresentation(0,blockOwned) self.petsc_l2g = p4pyPETSc.LGMap() self.petsc_l2g.create(self.subdomain2global) self.colind_global = self.petsc_l2g.apply(self.csr_rep_owned[1]) #prealloc needs global indices self.setPreallocationCSR([self.csr_rep_owned[0],self.colind_global,self.csr_rep_owned[2]]) self.setUp() self.setLGMap(self.petsc_l2g) self.setFromOptions()
def calculate(self): import numpy import Norms import FemTools t=0.0 nLevels = len(self.mlTransport.uList) assert nLevels > 1, "Need at least two grids for hierarchical mesh estimate" coefficients = self.mlTransport.modelList[-1].coefficients mCoarse = self.mlTransport.modelList[-2] uCoarse = self.mlTransport.modelList[-2].u mFine = self.mlTransport.modelList[-1] uFine = self.mlTransport.modelList[-1].u proj_uCoarse = [FemTools.FiniteElementFunction(mFine.u[ci].femSpace) for ci in range(coefficients.nc)] proj_uCoarse_q = [numpy.zeros(mFine.q[('u',ci)].shape,'d') for ci in range(coefficients.nc)] elementError = [numpy.zeros((mFine.mesh.nElements_global,),'d') for ci in range(coefficients.nc)] elementTagArray = numpy.zeros((mFine.mesh.nElements_global,),'i') elementTagArray.flat[:]=0.0 localRefinement=False error = 0.0 for ci in range(coefficients.nc): self.mlTransport.meshTransfers.prolong_bcListDict[ci][-1].matvec(uCoarse[ci].dof, proj_uCoarse[ci].dof) #load Dirichlet conditions in for dofN,g in mFine.dirichletConditions[ci].DOFBoundaryConditionsDict.iteritems(): proj_uCoarse[ci].dof[dofN] = g(mFine.dirichletConditions[ci].DOFBoundaryPointDict[dofN],t) proj_uCoarse[ci].getValues(mFine.q['v',ci],proj_uCoarse_q[ci]) error += Norms.L2errorSFEM_local(mFine.q[('dV_u',ci)], mFine.q[('u',ci)], proj_uCoarse_q[ci], elementError[ci]) for eN in range(mFine.mesh.nElements_global): if (mFine.mesh.nElements_global*elementError[ci][eN]/error) > 5.0: elementTagArray[eN] = 1 localRefinement=True if not localRefinement: elementTagArray.flat[:]=1 logEvent("error "+`error`,level=3)#mwf debug turn off,"elementTagArray",elementTagArray return (error,elementTagArray)
def JONSWAP(f,f0,Hs,g,gamma,TMA=False, h = -10): """The wave spectrum from Joint North Sea Wave Observation Project :param f: wave frequency [1/T] :param f0: peak frequency [1/T] :param Hs: significant wave height [L] :param g: gravity [L/T^2] :param gamma: peak enhancement factor [-] """ omega = 2.0*pi*f omega0 = 2.0*pi*f0 alpha = 2.0*pi*0.0624*(1.094-0.01915*log(gamma))/(0.23+0.0336*gamma-0.0185/(1.9+gamma)) r = np.exp(- (omega-omega0)**2/(2*sigma(omega,omega0)**2*omega0**2)) tma = 1. if TMA: if (h < 0): logEvent("Wavetools:py. Provide valid depth definition definition for TMA spectrum") logEvent("Wavetools:py. Stopping simulation") exit(1) k = dispersion(2*pi*f,h) tma = tanh(k*h)*tanh(k*h)/(1.+ 2.*k*h/sinh(k*h)) return (tma * alpha*Hs**2*omega0**4/omega**5)*np.exp(-(5.0/4.0)*(omega0/omega)**4)*gamma**r
def reconstruct_window(self,x,y,z,t,Nf,var="eta",ss = "x"): "Direct reconstruction of a timeseries" if self.rec_direct==False: logEvent("WaveTools.py: While attempting direct reconstruction, wrong input for rec_direct found (should be set to True)",level=0) logEvent("Stopping simulation",level=0) exit(1) ai = self.decomp[1] ipeak = np.where(ai == max(ai))[0][0] imax = min(ipeak + Nf/2,len(ai)) imin = max(0,ipeak - Nf/2) ai = ai[imin:imax] omega = self.decomp[0][imin:imax] phi = self.decomp[2][imin:imax] ki = dispersion(omega,self.depth,g=self.gAbs) kDir = np.zeros((len(ki),3),"d") Nf = len(omega) for ii in range(len(ki)): kDir[ii,:] = ki[ii]*self.waveDir[:] if var=="eta": Eta=0. for ii in range(Nf): Eta+=ai[ii]*cos(x*kDir[ii,0]+y*kDir[ii,1]+z*kDir[ii,2] - omega[ii]*t - phi[ii]) return Eta if var=="U": UH=0. UV=0. for ii in range(Nf): UH+=ai[ii]*omega[ii]*cosh(ki[ii]*(Z(x,y,z)+depth))*cos(x*kDir[ii,0]+y*kDir[ii,1]+z*kDir[ii,2] - omega[ii]*t + phi[ii])/sinh(ki[ii]*depth) UV+=ai[ii]*omega[ii]*sinh(ki[ii]*(Z(x,y,z)+depth))*sin(x*kDir[ii,0]+y*kDir[ii,1]+z*kDir[ii,2] - omega[ii]*t + phi[ii])/sinh(ki[ii]*depth) #waves(period = 1./self.fi[ii], waveHeight = 2.*self.ai[ii],mwl = self.mwl, depth = self.d,g = self.g,waveDir = self.waveDir,wavelength=self.wi[ii], phi0 = self.phi[ii]).u(x,y,z,t) Vcomp = { "x":UH*self.waveDir[0] + UV*self.vDir[0], "y":UH*self.waveDir[1] + UV*self.vDir[1], "z":UH*self.waveDir[2] + UV*self.vDir[2], } return Vcomp[ss]
def u(self,x,y,z,t,ss = "x"): """x-component of velocity :param x: floating point x coordinate :param z: floating point z coordinate (height above bottom) :param t: time """ UH=0. UV=0. ii=0. if self.waveType is "Linear": UH+=self.amplitude*self.omega*cosh(self.k*(self.Z(x,y,z)+self.depth))*cos(self.phase(x,y,z,t))/sinh(self.k*self.depth) UV+=self.omega*self.amplitude*sinh(self.k*(self.Z(x,y,z)+self.depth))*sin(self.phase(x,y,z,t))/sinh(self.k*self.depth) #waves(period = 1./self.fi[ii], waveHeight = 2.*self.ai[ii],mwl = self.mwl, depth = self.d,g = self.g,waveDir = self.waveDir,wavelength=self.wi[ii], phi0 = self.phi[ii]).u(x,y,z,t) Vcomp = { "x":UH*self.waveDir[0] + UV*self.vDir[0], "y":UH*self.waveDir[1] + UV*self.vDir[1], "z":UH*self.waveDir[2] + UV*self.vDir[2], } elif self.waveType is "Fenton": for B in self.Bcoeff: ii+=1 UV+=ii*B*sinh(self.k*(self.Z(x,y,z)+self.depth))*sin(self.phase(x,y,z,t))/cosh(self.k*self.depth) UH+=ii*B*cosh(self.k*(self.Z(x,y,z)+self.depth))*cos(self.phase(x,y,z,t))/cosh(self.k*self.depth) #waves(period = 1./self.fi[ii], waveHeight = 2.*self.ai[ii],mwl = self.mwl, depth = self.d,g = self.g,waveDir = self.waveDir,wavelength=self.wi[ii], phi0 = self.phi[ii]).u(x,y,z,t) Vcomp = { "x":UH*self.waveDir[0] + UV*self.vDir[0], "y":UH*self.waveDir[1] + UV*self.vDir[1], "z":UH*self.waveDir[2] + UV*self.vDir[2], } else: logEvent("Check Wave types. Available wave types are %s" % waveType,level=0) exit(1) return Vcomp[ss]
def __init__(self, timeSeriesFile= "Timeseries.txt", skiprows = 0, d = 2.0, Npeaks = 1, #m depth bandFactor = [2.0], #controls width of band around fp peakFrequencies = [0.2], N = 32, #number of frequency bins Nwaves = 4, #Nmumber of waves per windowmean water level mwl = 0.0, #mean water level waveDir = np.array([1,0,0]), #accelerationof gravity g = np.array([0, -9.81, 0]), rec_direct = False ): self.depth = d self.Npeaks = Npeaks if Npeaks is not len(bandFactor): logEvent("WaveTools.py: bandFactor entries in should be as many as the number of frequencies",level=0) logEvent("Stopping simulation",level=0) exit(1) if Npeaks is not len(peakFrequencies): logEvent("WaveTools.py: peakFrequencies entries in should be as many as the number of frequencies",level=0) logEvent("Stopping simulation",level=0) exit(1) self.rec_direct= rec_direct self.bandFactor = np.array(bandFactor) self.peakFrequencies = np.array(peakFrequencies) self.N = N self.Nwaves = Nwaves self.mwl = mwl self.waveDir = waveDir/sqrt(sum(waveDir * waveDir)) self.g = np.array(g) #derived variables self.gAbs = sqrt(sum(g * g)) self.vDir = self.g/self.gAbs self.fmax = self.bandFactor*self.peakFrequencies self.fmin = self.peakFrequencies/self.bandFactor self.df = (self.fmax-self.fmin)/float(self.N-1) self.fi=np.zeros((self.N,self.Npeaks),'d') for j in range(Npeaks): for i in range(N): self.fi[i,j] = self.fmin[j]+self.df[j]*i self.omegai = 2.*pi*self.fi self.ki = dispersion(self.omegai,self.depth,g=self.gAbs) self.wi = 2.*pi/self.ki #Reading time series filetype = timeSeriesFile[-4:] logEvent("Reading timeseries from %s file: %s" % (filetype,timeSeriesFile),level=0) fid = open(timeSeriesFile,"r") if (filetype !=".txt") and (filetype != ".csv"): logEvent("WaveTools.py: Timeseries must be given in .txt or .csv format",level=0) logEvent("Stopping simulation",level=0) sys.exit(1) elif (filetype == ".csv"): tdata = np.loadtxt(fid,skiprows=skiprows,delimiter=",") else: tdata = np.loadtxt(fid,skiprows=skiprows) fid.close() #Checks for tseries file ncols = len(tdata[0,:]) if ncols != 2: logEvent("WaveTools.py: Timeseries file must have only two columns [time, eta]",level=0) logEvent("Stopping simulation",level=0) sys.exit(1) time_temp = tdata[:,0] self.dt = (time_temp[-1]-time_temp[0])/len(time_temp) doInterp = False for i in range(1,len(time_temp)): dt_temp = time_temp[i]-time_temp[i-1] #check if time is at first column if time_temp[i]<time_temp[i-1]: logEvent("WaveTools.py: Found not consistent time entry between %s and %s row. Time variable must be always at the first column of the file and increasing monotonically" %(i-1,i) ) logEvent("Stopping simulation",level=0) sys.exit(1) #check if sampling rate is constant if abs(dt_temp-self.dt)/self.dt <= 1e-4: doInterp = True if(doInterp): logEvent("WaveTools.py: Not constant sampling rate found, proceeding to signal interpolation to a constant sampling rate",level=0) self.time = np.linspace(time_temp[0],time_temp[-1],len(time_temp)) self.eta = np.interp(self.time,time_temp,tdata[:,1]) else: self.time = time_temp self.eta = tdata[:,1] self.eta -=np.mean(self.eta) wind_fun = window(wname="Costap") self.eta *=wind_fun(len(self.time),tail=0.05) del tdata self.tlength = (self.time[-1]-self.time[0]) windows_span = [] windows_rec = [] # Direct decomposition of the time series for using at reconstruct_direct if (self.rec_direct): self.nfft=len(self.time) self.decomp = decompose_tseries(self.time,self.eta,self.nfft,ret_only_freq=0) self.setup = self.decomp[3] # Spectral windowing else: #setting the window duration (approx.). Twindow = Tmean * Nwaves = Tpeak * Nwaves /1.1 self.Twindow = self.Nwaves / (1.1 * self.peakFrequencies ) print self.Twindow #Settling overlap 25% of Twindow self.Toverlap = 0.25 * self.Twindow #Getting the actual number of windows # (N-1) * (Twindow - Toverlap) + Twindow self.Nwindows = int( (self.tlength - self.Twindow ) / (self.Twindow - self.Toverlap) ) + 1 # Correct Twindow and Toverlap for duration self.Twindow = self.tlength/(1. + 0.75*(self.Nwindows)) self.Toverlap = 0.25*self.Twindow logEvent("WaveTools.py: Correcting window duration for matching the exact time range of the series. Window duration correspond to %s waves approx." %(self.Twindow * 1.1* self.peakFrequencies) ) diff = self.Nwindows*(self.Twindow -self.Toverlap)+self.Twindow - self.tlength logEvent("WaveTools.py: Checking duration of windowed time series: %s per cent difference from original duration" %(100*diff) ) logEvent("WaveTools.py: Using %s windows for reconstruction with %s sec duration and 25 per cent overlap" %(self.Nwindows, self.Twindow) ) for jj in range(self.Nwindows): span = np.zeros(2,"d") tfirst = self.time[0] + self.Twindow tlast = self.time[-1] - self.Twindow if jj == 0: ispan1 = 0 ispan2 = np.where(self.time> tfirst)[0][0] elif jj == self.Nwindows: ispan1 = np.where(self.time > tlast)[0][0] ispan2 = len(self.time) else: tstart = self.time[ispan2] - self.Toverlap ispan1 = np.where(self.time > tstart)[0][0] ispan2 = np.where(self.time > tstart + self.Twindow )[0][0] span[0] = ispan1 span[1] = ispan2 windows_span.append(span) windows_rec.append(np.array(zip(self.time[ispan1:ispan2],self.eta[ispan1:ispan2]))) print jj # print (self.Twindow) # print("number of windows: %s" % self.Nwindows) # print(self.Nwindows*(self.Twindow -self.Toverlap)+self.Twindow ) # print(self.tlength) self.decompose_window = [] style = "k-" for wind in windows_rec: self.nfft=len(wind[:,0]) decomp = decompose_tseries(wind[:,0],wind[:,1],self.nfft,ret_only_freq=0) self.decompose_window.append(decomp) if style == "k-": style = "kx" else: style ="k-" plt.plot(wind[:,0],wind[:,1],style) plt.savefig("rec.pdf")
def calculate(self): #cek hack for min self.minX_neg=1.0e10 self.maxX_neg=-1.0e10 self.minX=1.0e10 self.maxX=-1.0e10 self.maxX_domain=-1.0e10 self.minX_domain=1.0e10 for l,m in enumerate(self.model.levelModelList): for eN in range(m.mesh.nElements_global): for nN in range(m.mesh.nNodes_element): x = m.mesh.nodeArray[m.mesh.elementNodesArray[eN,nN]][0] u = m.u[1].dof[m.mesh.elementNodesArray[eN,nN]] if x > self.maxX_domain: self.maxX_domain = x if x < self.minX_domain: self.minX_domain = x if u < 0.0: if x > self.maxX_neg: self.maxX_neg = x if x > self.maxX: self.maxX = x #check to see if 0 contour is further to right for nN_neigh in range(0,nN)+range(nN+1,m.mesh.nNodes_element): u2 = m.u[1].dof[m.mesh.elementNodesArray[eN,nN_neigh]] x2 = m.mesh.nodeArray[m.mesh.elementNodesArray[eN,nN_neigh]][0] if x2 > x: if u2 >=0.0: x0 = x - u*(x2-x)/(u2-u) if x0 > self.maxX: self.maxX=x0 if x < self.minX_neg: self.minX_neg = x if x < self.minX: self.minX = x #check to see if 0 contour is further to right for nN_neigh in range(0,nN)+range(nN+1,m.mesh.nNodes_element): u2 = m.u[1].dof[m.mesh.elementNodesArray[eN,nN_neigh]] x2 = m.mesh.nodeArray[m.mesh.elementNodesArray[eN,nN_neigh]][0] if x2 < x: if u2 >=0.0: x0 = x - u*(x2-x)/(u2-u) if x0 < self.minX: self.minX=x0 #catch case with zero recirculation if self.minX > self.maxX_domain: self.minX = self.minX_domain if self.maxX < self.minX_domain: self.maxX = self.minX_domain if self.rcStartX != None: if self.maxX > self.rcStartX: self.levelLlist.append(self.maxX-self.rcStartX) else: self.levelLlist.append(0.0) else: self.levelLlist.append(self.maxX-self.minX) #self.historyL.append(copy.deepcopy(self.levelLlist)) #self.writeScalarXdmf(self.levelLlist,"Recirculation Length") # if self.dataStorage != None: # tmp = self.dataStorage['RecirculationLengthHistory'] # tmp.append(self.levelLlist) # self.dataStorage['RecirculationLengthHistory']=tmp # try: # self.viewL() # except: # pass logEvent("Recirculation Length "+`self.levelLlist[-1]`)
def __init__(self, ghosted_csr_mat=None, par_bs=None, par_n=None, par_N=None, par_nghost=None, subdomain2global=None, blockVecType="simple", pde=None, par_nc=None, par_Nc=None, proteus_jacobian=None, nzval_proteus2petsc=None): p4pyPETSc.Mat.__init__(self) if ghosted_csr_mat == None: return #when duplicating for petsc usage self.pde = pde if par_nc == None: par_nc = par_n if par_Nc == None: par_Nc = par_N self.proteus_jacobian = proteus_jacobian self.nzval_proteus2petsc = nzval_proteus2petsc self.ghosted_csr_mat = ghosted_csr_mat self.blockVecType = blockVecType assert self.blockVecType == "simple", "petsc4py wrappers require self.blockVecType=simple" self.create(p4pyPETSc.COMM_WORLD) self.blockSize = max(1, par_bs) if self.blockSize > 1 and blockVecType != "simple": ## \todo fix block aij in ParMat_petsc4py self.setType('baij') self.setSizes([[self.blockSize * par_n, self.blockSize * par_N], [self.blockSize * par_nc, self.blockSize * par_Nc]], bsize=self.blockSize) self.setBlockSize(self.blockSize) self.subdomain2global = subdomain2global #no need to include extra block dofs? else: self.setType('aij') self.setSizes([[par_n * self.blockSize, par_N * self.blockSize], [par_nc * self.blockSize, par_Nc * self.blockSize]], bsize=1) if self.blockSize > 1: #have to build in block dofs subdomain2globalTotal = numpy.zeros( (self.blockSize * subdomain2global.shape[0], ), 'i') for j in range(self.blockSize): subdomain2globalTotal[ j::self. blockSize] = subdomain2global * self.blockSize + j self.subdomain2global = subdomain2globalTotal else: self.subdomain2global = subdomain2global from proteus import Comm comm = Comm.get() logEvent( "ParMat_petsc4py comm.rank= %s blockSize = %s par_n= %s par_N=%s par_nghost=%s par_jacobian.getSizes()= %s " % (comm.rank(), self.blockSize, par_n, par_N, par_nghost, self.getSizes())) self.csr_rep = ghosted_csr_mat.getCSRrepresentation() if self.proteus_jacobian != None: self.proteus_csr_rep = self.proteus_jacobian.getCSRrepresentation() if self.blockSize > 1: blockOwned = self.blockSize * par_n self.csr_rep_local = ghosted_csr_mat.getSubMatCSRrepresentation( 0, blockOwned) else: self.csr_rep_local = ghosted_csr_mat.getSubMatCSRrepresentation( 0, par_n) self.petsc_l2g = p4pyPETSc.LGMap() self.petsc_l2g.create(self.subdomain2global) self.setUp() self.setLGMap(self.petsc_l2g) # self.colind_global = self.petsc_l2g.apply( self.csr_rep_local[1]) #prealloc needs global indices self.setPreallocationCSR( [self.csr_rep_local[0], self.colind_global, self.csr_rep_local[2]]) self.setFromOptions()
def __init__( self, timeSeriesFile="Timeseries.txt", skiprows=0, d=2.0, Npeaks=1, #m depth bandFactor=[2.0], #controls width of band around fp peakFrequencies=[0.2], N=32, #number of frequency bins Nwaves=4, #Nmumber of waves per windowmean water level mwl=0.0, #mean water level waveDir=np.array([1, 0, 0]), #accelerationof gravity g=np.array([0, -9.81, 0]), rec_direct=False): self.depth = d self.Npeaks = Npeaks if Npeaks is not len(bandFactor): logEvent( "WaveTools.py: bandFactor entries in should be as many as the number of frequencies", level=0) logEvent("Stopping simulation", level=0) exit(1) if Npeaks is not len(peakFrequencies): logEvent( "WaveTools.py: peakFrequencies entries in should be as many as the number of frequencies", level=0) logEvent("Stopping simulation", level=0) exit(1) self.rec_direct = rec_direct self.bandFactor = np.array(bandFactor) self.peakFrequencies = np.array(peakFrequencies) self.N = N self.Nwaves = Nwaves self.mwl = mwl self.waveDir = waveDir / sqrt(sum(waveDir * waveDir)) self.g = np.array(g) #derived variables self.gAbs = sqrt(sum(g * g)) self.vDir = self.g / self.gAbs self.fmax = self.bandFactor * self.peakFrequencies self.fmin = self.peakFrequencies / self.bandFactor self.df = (self.fmax - self.fmin) / float(self.N - 1) self.fi = np.zeros((self.N, self.Npeaks), 'd') for j in range(Npeaks): for i in range(N): self.fi[i, j] = self.fmin[j] + self.df[j] * i self.omegai = 2. * pi * self.fi self.ki = dispersion(self.omegai, self.depth, g=self.gAbs) self.wi = 2. * pi / self.ki #Reading time series filetype = timeSeriesFile[-4:] logEvent("Reading timeseries from %s file: %s" % (filetype, timeSeriesFile), level=0) fid = open(timeSeriesFile, "r") if (filetype != ".txt") and (filetype != ".csv"): logEvent( "WaveTools.py: Timeseries must be given in .txt or .csv format", level=0) logEvent("Stopping simulation", level=0) sys.exit(1) elif (filetype == ".csv"): tdata = np.loadtxt(fid, skiprows=skiprows, delimiter=",") else: tdata = np.loadtxt(fid, skiprows=skiprows) fid.close() #Checks for tseries file ncols = len(tdata[0, :]) if ncols != 2: logEvent( "WaveTools.py: Timeseries file must have only two columns [time, eta]", level=0) logEvent("Stopping simulation", level=0) sys.exit(1) time_temp = tdata[:, 0] self.dt = (time_temp[-1] - time_temp[0]) / len(time_temp) doInterp = False for i in range(1, len(time_temp)): dt_temp = time_temp[i] - time_temp[i - 1] #check if time is at first column if time_temp[i] < time_temp[i - 1]: logEvent( "WaveTools.py: Found not consistent time entry between %s and %s row. Time variable must be always at the first column of the file and increasing monotonically" % (i - 1, i)) logEvent("Stopping simulation", level=0) sys.exit(1) #check if sampling rate is constant if abs(dt_temp - self.dt) / self.dt <= 1e-4: doInterp = True if (doInterp): logEvent( "WaveTools.py: Not constant sampling rate found, proceeding to signal interpolation to a constant sampling rate", level=0) self.time = np.linspace(time_temp[0], time_temp[-1], len(time_temp)) self.eta = np.interp(self.time, time_temp, tdata[:, 1]) else: self.time = time_temp self.eta = tdata[:, 1] self.eta -= np.mean(self.eta) wind_fun = window(wname="Costap") self.eta *= wind_fun(len(self.time), tail=0.05) del tdata self.tlength = (self.time[-1] - self.time[0]) windows_span = [] windows_rec = [] # Direct decomposition of the time series for using at reconstruct_direct if (self.rec_direct): self.nfft = len(self.time) self.decomp = decompose_tseries(self.time, self.eta, self.nfft, ret_only_freq=0) self.setup = self.decomp[3] # Spectral windowing else: #setting the window duration (approx.). Twindow = Tmean * Nwaves = Tpeak * Nwaves /1.1 self.Twindow = self.Nwaves / (1.1 * self.peakFrequencies) print self.Twindow #Settling overlap 25% of Twindow self.Toverlap = 0.25 * self.Twindow #Getting the actual number of windows # (N-1) * (Twindow - Toverlap) + Twindow self.Nwindows = int((self.tlength - self.Twindow) / (self.Twindow - self.Toverlap)) + 1 # Correct Twindow and Toverlap for duration self.Twindow = self.tlength / (1. + 0.75 * (self.Nwindows)) self.Toverlap = 0.25 * self.Twindow logEvent( "WaveTools.py: Correcting window duration for matching the exact time range of the series. Window duration correspond to %s waves approx." % (self.Twindow * 1.1 * self.peakFrequencies)) diff = self.Nwindows * ( self.Twindow - self.Toverlap) + self.Twindow - self.tlength logEvent( "WaveTools.py: Checking duration of windowed time series: %s per cent difference from original duration" % (100 * diff)) logEvent( "WaveTools.py: Using %s windows for reconstruction with %s sec duration and 25 per cent overlap" % (self.Nwindows, self.Twindow)) for jj in range(self.Nwindows): span = np.zeros(2, "d") tfirst = self.time[0] + self.Twindow tlast = self.time[-1] - self.Twindow if jj == 0: ispan1 = 0 ispan2 = np.where(self.time > tfirst)[0][0] elif jj == self.Nwindows: ispan1 = np.where(self.time > tlast)[0][0] ispan2 = len(self.time) else: tstart = self.time[ispan2] - self.Toverlap ispan1 = np.where(self.time > tstart)[0][0] ispan2 = np.where(self.time > tstart + self.Twindow)[0][0] span[0] = ispan1 span[1] = ispan2 windows_span.append(span) windows_rec.append( np.array( zip(self.time[ispan1:ispan2], self.eta[ispan1:ispan2]))) print jj # print (self.Twindow) # print("number of windows: %s" % self.Nwindows) # print(self.Nwindows*(self.Twindow -self.Toverlap)+self.Twindow ) # print(self.tlength) self.decompose_window = [] style = "k-" for wind in windows_rec: self.nfft = len(wind[:, 0]) decomp = decompose_tseries(wind[:, 0], wind[:, 1], self.nfft, ret_only_freq=0) self.decompose_window.append(decomp) if style == "k-": style = "kx" else: style = "k-" plt.plot(wind[:, 0], wind[:, 1], style) plt.savefig("rec.pdf")