class SimpleStokesProblem(SaddlePointProblem): """ simple example of saddle point problem """ def __init__(self,domain): super(SimpleStokesProblem, self).__init__(self) self.__pde_u=LinearPDE(domain) self.__pde_u.setSymmetryOn() self.__pde_u.setValue(A=identityTensor4(dom)) self.__pde_p=LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() self.__pde_p.setValue(D=1.) def initialize(self,f=Data(),fixed_u_mask=Data()): self.__pde_u.setValue(q=fixed_u_mask,Y=f) def inner(self,p0,p1): return integrate(p0*p1,Function(self.__pde_p.getDomain())) def solve_f(self,u,p,tol=1.e-8): self.__pde_u.setTolerance(tol) self.__pde_u.setValue(X=grad(u)+p*kronecker(self.__pde_u.getDomain())) return self.__pde_u.getSolution() def solve_g(self,u,tol=1.e-8): self.__pde_p.setTolerance(tol) self.__pde_p.setValue(X=-u) dp=self.__pde_p.getSolution() return dp
class SimpleStokesProblem(SaddlePointProblem): """ simple example of saddle point problem """ def __init__(self, domain): super(SimpleStokesProblem, self).__init__(self) self.__pde_u = LinearPDE(domain) self.__pde_u.setSymmetryOn() self.__pde_u.setValue(A=identityTensor4(dom)) self.__pde_p = LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() self.__pde_p.setValue(D=1.) def initialize(self, f=Data(), fixed_u_mask=Data()): self.__pde_u.setValue(q=fixed_u_mask, Y=f) def inner(self, p0, p1): return integrate(p0 * p1, Function(self.__pde_p.getDomain())) def solve_f(self, u, p, tol=1.e-8): self.__pde_u.setTolerance(tol) self.__pde_u.setValue(X=grad(u) + p * kronecker(self.__pde_u.getDomain())) return self.__pde_u.getSolution() def solve_g(self, u, tol=1.e-8): self.__pde_p.setTolerance(tol) self.__pde_p.setValue(X=-u) dp = self.__pde_p.getSolution() return dp
class StokesProblem(SaddlePointProblem): """ simple example of saddle point problem """ def __init__(self, domain, debug=False): super(StokesProblem, self).__init__(self, debug) self.domain = domain self.__pde_u = LinearPDE(domain, numEquations=self.domain.getDim(), numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn() self.__pde_p = LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() def initialize(self, f=Data(), fixed_u_mask=Data(), eta=1): self.eta = eta A = self.__pde_u.createCoefficientOfGeneralPDE("A") for i in range(self.domain.getDim()): for j in range(self.domain.getDim()): A[i, j, j, i] += self.eta A[i, j, i, j] += self.eta self.__pde_p.setValue(D=1 / self.eta) self.__pde_u.setValue(A=A, q=fixed_u_mask, Y=f) def inner(self, p0, p1): return integrate(p0 * p1, Function(self.__pde_p.getDomain())) def solve_f(self, u, p, tol=1.e-8): self.__pde_u.setTolerance(tol) g = grad(u) self.__pde_u.setValue(X=self.eta * symmetric(g) + p * kronecker(self.__pde_u.getDomain())) return self.__pde_u.getSolution() def solve_g(self, u, tol=1.e-8): self.__pde_p.setTolerance(tol) self.__pde_p.setValue(X=-u) dp = self.__pde_p.getSolution() return dp
class StokesProblem(SaddlePointProblem): """ simple example of saddle point problem """ def __init__(self,domain,debug=False): super(StokesProblem, self).__init__(self,debug) self.domain=domain self.__pde_u=LinearPDE(domain,numEquations=self.domain.getDim(),numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn() self.__pde_p=LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() def initialize(self,f=Data(),fixed_u_mask=Data(),eta=1): self.eta=eta A =self.__pde_u.createCoefficientOfGeneralPDE("A") for i in range(self.domain.getDim()): for j in range(self.domain.getDim()): A[i,j,j,i] += self.eta A[i,j,i,j] += self.eta self.__pde_p.setValue(D=1/self.eta) self.__pde_u.setValue(A=A,q=fixed_u_mask,Y=f) def inner(self,p0,p1): return integrate(p0*p1,Function(self.__pde_p.getDomain())) def solve_f(self,u,p,tol=1.e-8): self.__pde_u.setTolerance(tol) g=grad(u) self.__pde_u.setValue(X=self.eta*symmetric(g)+p*kronecker(self.__pde_u.getDomain())) return self.__pde_u.getSolution() def solve_g(self,u,tol=1.e-8): self.__pde_p.setTolerance(tol) self.__pde_p.setValue(X=-u) dp=self.__pde_p.getSolution() return dp
class SonicWaveInFrequencyDomain(object): """ This class is a simple wrapper for the solution of the 2D or 3D sonic wave equtaion in the frequency domain. It solves complex PDE div (grad p) - k^2 p = Q where k = omega/c Q = source term : Dirac function Boundary conditions implemented are NEED TO SET PML CONDITION FIRST - perfectly matched layer : see class PMLCondition - fixed BC - all but the top surface It has functions - getDomain - setFrequency - setVp Output solution - getWave """ def __init__(self, domain, pml_condition=None, frequency=None, vp=None, fix_boundary=True): """ Initialise the class with domain, boundary conditions and frequency. Setup PDE :param domain: the domain : setup with Dirac points :type domain: `Domain` :param pml_condition: :type pml_condition: :param frequency: :type frequency: :param vp: velocity field :type vp: `Data` :param fix_boundary: if true fix all the boundaries except the top :type fix_boundary: `bool` """ Dim=domain.getDim() self.pde=LinearPDE(domain, numEquations=1, numSolutions=1, isComplex=True) self.pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.pml=pml_condition if not self.pml: self.pde.setValue(A=kronecker(domain)) self.J=1. if fix_boundary: x=domain.getX() q=whereZero(x[Dim-1]-inf(x[Dim-1])) for i in range(Dim-1): q+=whereZero(x[i]-inf(x[i]))+whereZero(x[i]-sup(x[i])) self.pde.setValue(q=q) self.setFrequency(frequency) self.setVp(vp) def getDomain(self): """ returns the domain """ return self.pde.getDomain() def setFrequency(self, frequency): """ sets the frequency """ self.frequency=frequency self.newFreq=True return self def setVp(self, vp): """ sets the velocity for the rock """ self.newVp=True if vp is None: self.sigma2=None else: self.sigma2=1./vp**2 return self def getWave(self, source): """ solve the PDE """ omega=self.frequency*2*np.pi if self.pml and self.newFreq: Dim=self.getDomain().getDim() A=kronecker(Function(self.getDomain())) alpha, J = self.pml.getPMLWeights(self.getDomain(), omega=omega) for d in range(Dim): A[d,d]=J/alpha[d]**2 self.J=J self.pde.setValue(A=A) if self.newFreq or self.newVp: if self.frequency is None or self.sigma2 is None: raise ValueError("freqency/propagation speed vp is not set.") omega=self.frequency*2*np.pi self.pde.setValue(D=-self.J*omega**2*self.sigma2) self.newFreq=False self.newVp=False self.pde.setValue(y_dirac=source) return self.pde.getSolution()