Beispiel #1
0
 def __init__(self,
              L,
              epsilon,
              Eb=1,
              mu=1,
              N=16,
              deltaLocal=1,
              NupsampleForDirect=64,
              nptsUniform=16,
              rigid=False):
     super().__init__(L, epsilon, Eb, mu, N, NupsampleForDirect,
                      nptsUniform, rigid)
     # Chebyshev grid and weights
     self._s = cf.chebPts(self._N, [0, self._L], chebGridType)
     self._w = cf.chebWts(self._N, [0, self._L], chebGridType)
     self._w2N = cf.chebWts(2 * self._N, [0, self._L], chebGridType)
     self._wForDirect = cf.chebWts(self._nptsDirect, [0, self._L],
                                   chebGridType)
     # Chebyshev initializations
     self._Lmat = cf.CoeffstoValuesMatrix(self._N, self._N, chebGridType)
     self._LUCoeffs = lu_factor(self._Lmat)
     self.initIs()
     self.initFPMatrix()
     self.initLocalcvals(deltaLocal)
     self.initDiffMatrices()
     self.initD4BC()
     self.initResamplingMatrices()
     self.initSpecialQuadMatrices()
Beispiel #2
0
 def newNodes(self, Nrs, typetarg=chebGridType, numPanels=1):
     """
     New Chebyshev nodes
     Inputs: Nrs = number of new nodes, typetarg = type of new nodes
     Outputs: new nodes sNew
     """
     sNew = cf.chebPts(Nrs, [0, self._L], typetarg, numPanels)
     return sNew
Beispiel #3
0
 def initSpecialQuadMatrices(self):
     """
     Initialize matrices that are necessary for special quadrature / resampling.
     """
     self._MatfromNtoUpsamp = cf.ResamplingMatrix(self._nptsUpsample,
                                                  self._N, chebGridType,
                                                  chebGridType)
     self._MatfromNto2panUp = cf.ResamplingMatrix(self._nptsUpsample,self._N,chebGridType,chebGridType,\
                 nPantarg=2)
     self._MatfromNtoUniform = cf.ResamplingMatrix(self._nptsUniform,
                                                   self._N, 'u',
                                                   chebGridType)
     self._UpsampledCoefficientsMatrix = cf.CoeffstoValuesMatrix(
         self._nptsUpsample, self._nptsUpsample, chebGridType)
     self._UpsampCoeffLU = lu_factor(self._UpsampledCoefficientsMatrix)
     # Initialize LU factorization of vandermonde matrix for special quadrature
     self._specQuadNodes = cf.chebPts(self._nptsUpsample, [-1, 1],
                                      chebGridType)
     self._upsampledWeights = cf.chebWts(self._nptsUpsample, [0, self._L],
                                         chebGridType)
     self._NupsampLUpiv = lu_factor(
         np.vander(self._specQuadNodes, increasing=True).T)
 def initFPMatrix(self):
     """
     Initialize the matrix for the finite part integral. 
     Uses the adjoint method of Anna Karin Tornberg. 
     This method is distinct from the one in the parent class because it uses 
     numerical integration of Chebyshev polynomials instead of exact integration
     of monomials
     """
     sscale = -1 + 2 * self._s / self._L
     AllQs = np.zeros((self._N, self._N))
     AllDs = np.zeros((self._N, self._N))
     self._DoubletFPMatrix = np.zeros((self._N, self._N))
     self._Nsmall = 0
     self._RLess2aResamplingMat = np.zeros(
         (self._N * self._Nsmall, self._N))
     self._RLess2aWts = np.zeros(self._N * self._Nsmall)
     a = 0
     if (self._truRPYMob):
         a = self._a
     for iPt in range(self._N):
         s = self._s[iPt]
         eta = sscale[iPt]
         sLow = max(s - 2 * a, 0)
         sHi = min(s + 2 * a, self._L)
         etaLow = -1 + 2 * sLow / self._L
         etaHi = -1 + 2 * sHi / self._L
         # Compute integrals numerically to high accuracy
         q = np.zeros(self._N)
         qd = np.zeros(self._N)
         NoversampToCompute = 200
         # enough to get 10 digits
         for kk in range(self._N):
             if (etaLow > -1):
                 n = cf.chebPts(NoversampToCompute, [-1, etaLow], 1)
                 w = cf.chebWts(NoversampToCompute, [-1, etaLow], 1)
                 poly = np.cos(kk * np.arccos(n))
                 q[kk] = np.dot(w, ((n - eta) / np.abs(n - eta) * poly))
                 qd[kk] = np.dot(w, ((n - eta) / np.abs(n - eta)**3 * poly))
             if (etaHi < 1):
                 n = cf.chebPts(NoversampToCompute, [etaHi, 1], 1)
                 w = cf.chebWts(NoversampToCompute, [etaHi, 1], 1)
                 poly = np.cos(kk * np.arccos(n))
                 q[kk] += np.dot(w, ((n - eta) / np.abs(n - eta) * poly))
                 qd[kk] += np.dot(w,
                                  ((n - eta) / np.abs(n - eta)**3 * poly))
         AllQs[iPt, :] = q
         AllDs[iPt, :] = qd
     self._FPMatrix = 1.0 / (8.0 * np.pi *
                             self._mu) * 0.5 * self._L * np.linalg.solve(
                                 self._Lmat.T, AllQs.T)
     if (self._truRPYMob):
         self._DoubletFPMatrix = 1.0 / (
             8.0 * np.pi * self._mu) * 0.5 * self._L * np.linalg.solve(
                 self._Lmat.T, AllDs.T)
         # Initialize the resampling matrices for R < 2a
         # The only thing that can be precomputed are the matrices on [s-a, s] and [s,s+a] for resampling the
         # fiber positions
         # Each of these matrices is Nsmall/2 x N
         # So the total matrix is Nsmall x N for each point. What gets passed into C++ is the row stacked version
         # of the grand matrix, which is (N*Nsmall) x N
         self._Nsmall = 4
         if (self._epsilon > 1e-3):
             self._Nsmall = 8
         self._RLess2aResamplingMat = np.zeros(
             (self._N * self._Nsmall, self._N))
         self._RLess2aWts = np.zeros(self._N * self._Nsmall)
         for iPt in range(self._N):
             for iD in range(2):
                 dom = [
                     self._s[iPt],
                     min(self._s[iPt] + 2 * self._a, self._L)
                 ]
                 if (iD == 0):
                     dom = [
                         max(self._s[iPt] - 2 * self._a, 0), self._s[iPt]
                     ]
                 ssm = cf.chebPts(self._Nsmall // 2, dom, 'L')
                 wsm = cf.chebWts(self._Nsmall // 2, dom, 'L')
                 ChebCoeffsToVals = cf.CoeffstoValuesMatrix(
                     self._N, self._N, chebGridType)
                 LegCoeffsToVals = np.cos(
                     np.outer(np.arccos(2 * ssm / self._L - 1),
                              np.arange(self._N)))
                 self._RLess2aResamplingMat[iPt*self._Nsmall+iD*self._Nsmall//2:iPt*self._Nsmall+(iD+1)*self._Nsmall//2,:] =\
                  np.dot(LegCoeffsToVals,np.linalg.inv(ChebCoeffsToVals))
                 self._RLess2aWts[iPt * self._Nsmall + iD * self._Nsmall //
                                  2:iPt * self._Nsmall +
                                  (iD + 1) * self._Nsmall // 2] = wsm