def estimate(self, solution): mesh = solution.function_space().mesh() # Define cell and facet residuals R_T = -(self.rhs_f + div(grad(solution))) n = FacetNormal(mesh) R_dT = dot(grad(solution), n) # Will use space of constants to localize indicator form Constants = FunctionSpace(mesh, "DG", 0) w = TestFunction(Constants) h = CellSize(mesh) # Define form for assembling error indicators form = (h ** 2 * R_T ** 2 * w * dx + avg(h) * avg(R_dT) ** 2 * 2 * avg(w) * dS) # + h * R_dT ** 2 * w * ds) # Assemble error indicators indicators = assemble(form) # Calculate error error_estimate = sqrt(sum(i for i in indicators.array())) # Take sqrt of indicators indicators = np.array([sqrt(i) for i in indicators]) # Mark cells for refinement based on maximal marking strategy largest_error = max(indicators) cell_markers = MeshFunction("bool", mesh, mesh.topology().dim()) for c in cells(mesh): cell_markers[c] = indicators[c.index()] > (self.fraction * largest_error) return error_estimate, cell_markers
def calcMilesLerayDivFreeProjector(vectorFunction): vectorFunctionTemp = project(vectorFunction, V_vec) ### IF THIS FAILS IT WAS PROBABLY NOT A VECTOR FUNCTION diverg = project(div(vectorFunction),V) lastTerm = project(grad(calcInverseLaplacian(diverg)), V_vec) returnFunction = Function(V_vec) returnFunction.dat.data[:] = vectorFunctionTemp.dat.data[:] - lastTerm.dat.data[:] return returnFunction
def calcConstants_batscaleGammaUmiles(): ### recalculates the constants (batchelor scale, Gamma, U(in miles), tau, dominant wavelength for lap2lap global UinMiles global GammaInMiles global tauInMiles global l_bat global l_dom global l_root # miles p 5 UinMiles = abs(norm(u_adv,"l2")/(sqrt(L_x*L_y))) GammaInMiles = abs(norm(grad(u_adv),"l2")/(sqrt(L_x*L_y))) # irgendwie erkennt es sqrt variables immer als komplexe zahlen mit im part 0 an ... # miles p 16 tauInMiles = 1/GammaInMiles # miles p 34 if usedFlow in ['milesEnergy']: # miles: l_bat = 3/2*kappa/UinMiles elif usedFlow in ['milesEnstrophy']: l_bat = abs(sqrt(3/2*kappa*tauInMiles)) else: ### default energy but to see that it is strange put it negativ l_bat = -(3/2*kappa/UinMiles) if pdeShortName in ['advLap2Lap', 'kuraSiva']: # irgendwie erkennt es sqrt variables immer als komplexe zahlen mit im part 0 an ... l_dom = abs(2*sqrt(2)*pi) l_root = abs(2*pi) else: ### doesn't make sense but still compute and put - to indicate something strange l_dom = - abs(2*sqrt(2)*pi) l_root = - abs(2*pi)
def calcMilesOptimalFlowEnstrophyCase(function): funcFunction = project(function, V) invLap = calcInverseLaplacian(funcFunction) nablaInvLap = project(grad(invLap), V_vec) functionNablaLapInvFunction = Function(V_vec) functionNablaLapInvFunction.dat.data[:,0] = funcFunction.dat.data[:]*nablaInvLap.dat.data[:,0] functionNablaLapInvFunction.dat.data[:,1] = funcFunction.dat.data[:]*nablaInvLap.dat.data[:,1] projection = calcMilesLerayDivFreeProjector(functionNablaLapInvFunction) projectionX = Function(V) projectionY = Function(V) projectionX.dat.data[:] = projection.dat.data[:,0] projectionY.dat.data[:] = projection.dat.data[:,1] minNablaInvunctionNablaLapInvFunction = Function(V_vec) minNablaInvunctionNablaLapInvFunction.dat.data[:,0] = -calcInverseLaplacian(projectionX).dat.data[:] minNablaInvunctionNablaLapInvFunction.dat.data[:,1] = -calcInverseLaplacian(projectionY).dat.data[:] normalisationFactor = abs(sqrt(L_x*L_y))/(norm(grad(minNablaInvunctionNablaLapInvFunction),"l2")) ### in the code of miles they somehow use curl instead of grad #normalisationFactor = 1/(norm((minNablaInvunctionNablaLapInvFunction))) #print(normalisationFactor) retFunction = minNablaInvunctionNablaLapInvFunction retFunction.dat.data[:] = adv_scale*normalisationFactor*minNablaInvunctionNablaLapInvFunction.dat.data[:] return retFunction
def calcMilesOptimalFlowEnergyCase(function): funcFunction = project(function, V) invLap = calcInverseLaplacian(funcFunction) nablaInvLap = project(grad(invLap), V_vec) functionNablaLapInvFunction = Function(V_vec) functionNablaLapInvFunction.dat.data[:,0] = funcFunction.dat.data[:]*nablaInvLap.dat.data[:,0] functionNablaLapInvFunction.dat.data[:,1] = funcFunction.dat.data[:]*nablaInvLap.dat.data[:,1] projection = calcMilesLerayDivFreeProjector(functionNablaLapInvFunction) #normalisationFactor = 1/((calcSpatialAverage(calcAbsOfVectorFunction(projection))**2)**(1/2)) normalisationFactor = abs(sqrt(L_x*L_y))/(norm(projection,"l2")) #print(normalisationFactor) retFunction = projection retFunction.dat.data[:] = adv_scale*normalisationFactor*projection.dat.data[:] return retFunction
def calcInverseLaplacian(function): # returns lap^-1 f # f=function, u = outFunction # lap u = f # <lap u, v> =<f,v> # <-grad u, grad v> = <f,v> # <-grad u, grad v> - <f,v> = 0 # <grad u, grad v> + <f,v> = 0 #print("1",function.dat.data) if inverseLaplacianEnforceAverageFreeBefore: if norm(getZeroAverageOfScalarFunction(function)-function,"l2")>0.01*((L_x*L_y)**0.5): print("!!!warning!!! initial data of get inverse laplacian is non average free -> enforcing average free") function = getZeroAverageOfScalarFunction(function) outFunction = Function(V) testFunctionInvLap = TestFunction(V) F_invLap = (inner(grad(outFunction),grad(testFunctionInvLap))+dot(function,testFunctionInvLap))*dx solve(F_invLap == 0, outFunction) if inverseLaplacianEnforceAverageFreeAfter: if norm(getZeroAverageOfScalarFunction(outFunction)-outFunction,"l2")>0.01*((L_x*L_y)**0.5): print("!!!warning!!! result of get inverse laplacian is non average free -> enforcing average free") outFunction = getZeroAverageOfScalarFunction(outFunction) return outFunction
def writeOutputMeshFunctions(): outTheta1 = getOutputMeshFunctionScalar(theta, "theta") #outTheta2 = getOutputMeshFunctionScalar(theta, "theta (2)") #outTheta3 = getOutputMeshFunctionScalar(theta, "theta (3)") gradTheta = project(grad(theta), V_vec) outGradThetaX = getOutputMeshFunctionScalar(gradTheta, "d/dx theta", None, 0) outGradThetaY = getOutputMeshFunctionScalar(gradTheta, "d/dy theta", None, 1) outUadvX = getOutputMeshFunctionScalar(u_adv, "u_adv x", None, 0) outUadvY = getOutputMeshFunctionScalar(u_adv, "u_adv y", None, 1) #l_domFunction = Function(V).assign(l_dom) #outLdom = getOutputMeshFunctionScalar(None,"l_dominant", l_dom) #outfile_theta.write(outTheta1, outTheta2, outTheta3, outGradThetaX, outGradThetaY, outUadvX, outUadvY, outLdom, time=t) outfile_theta.write(outTheta1, outGradThetaX, outGradThetaY, outUadvX, outUadvY, time=t)
def calcCamillaTestFlow(function): #u_adv = theta nalba^-1 theta - nabla^-1(nabla theta cdot nabla^-1 theta) - nabla^-1 (theta^2) nablaMinusOneFunction = calcDivMinus1ofScalar(function) GradFunction = project(grad(function),V_vec) functionSq = Function(V) functionSq.dat.data[:] = function.dat.data[:]**2 firstTerm = Function(V_vec) firstTerm.dat.data[:,0] = function.dat.data[:]*nablaMinusOneFunction.dat.data[:,0] firstTerm.dat.data[:,1] = function.dat.data[:]*nablaMinusOneFunction.dat.data[:,1] secondTerm = calcDivMinus1ofScalar(calcCdotOfVectors(GradFunction, nablaMinusOneFunction)) thirdTerm = calcDivMinus1ofScalar(functionSq) result = Function(V_vec) result.dat.data[:] = firstTerm.dat.data[:]-secondTerm.dat.data[:]-thirdTerm.dat.data[:] normalisationFactor = abs(sqrt(L_x*L_y))/(norm(result,"l2")) result.dat.data[:] = adv_scale*normalisationFactor * result.dat.data[:] return result
### Variational scheme ### # Defining displacement space V = VectorFunctionSpace(mesh, finiteElement.family, finiteElement.order) # Stresss space S = TensorFunctionSpace(mesh, finiteElement.family, finiteElement.order) # Trial and test functions uTrial = TrialFunction(V) w = TestFunction(V) # weak operators massOp = physics.rho * inner(uTrial, w) * dx stiffOp = inner(elasticity.stress(physics.mu, physics.lmbda, uTrial), grad(w)) * dx # basisOp = [ inner(psi, w)*ds(i) for psi in psiBasis for i in range(geo.getNoFaces()) ] basisOp = [inner(psi, w) * ds(1) for psi in psiBasis] ## Matrices and vectors #M = PETScMatrix() #R = PETScMatrix() #P = [ PETScVector() for i in range(len(basisOp)) ] ## Assembling #assemble(massOp, tensor=M) #assemble(stiffOp, tensor=R) #[ assemble(basisOp[i], tensor=P[i]) for i in range(len(P)) ] # Assembling M = assemble(massOp)
### ### Variational scheme ### # Defining displacement space V = VectorFunctionSpace(mesh, finiteElement.family, finiteElement.order) # Stresss space S = TensorFunctionSpace(mesh, finiteElement.family, finiteElement.order) # Trial and test functions uTrial = TrialFunction(V) w = TestFunction(V) # weak operators massOp = physics.rho*inner(uTrial, w)*dx stiffOp = inner(elasticity.stress(physics.mu, physics.lmbda, uTrial), grad(w))*dx # Assembling M = assemble(massOp) R = assemble(stiffOp) ## Create zero boundary condition #bc = DirichletBC(V, Constant(geo.nDim*[0.0]), dirichletSubdomain) ## Construct dirichlet contribution vectors #dirichletM = PETScVector(MPI_COMM_WORLD, M.size(0)) #bc.zero(M) #bc.zero_columns(M, dirichletM, 1) #dirichletR = PETScVector(MPI_COMM_WORLD, R.size(0)) #bc.zero(R) #bc.zero_columns(R, dirichletR, 1)
def stress(mu, lmbda, u): Eps = sym(grad(u)) return 2.0 * mu * Eps + lmbda * tr(Eps) * Identity(len(u))
def calcDivMinus1ofScalar(function): # div^{-1} = div^{-1} divgrad laplace^{-1} = grad laplace^{-1} return project(grad(calcInverseLaplacian(function)),V_vec)
def calcLaplacian(function): gradFunction = project(grad(function), V_vec) return project(div(gradFunction),V)
testFunctionA, testFunctionB = TestFunctions(W) adv_scale ################################# ################################# ##### pde ##### F_nonLin = (inner((theta - theta_old)/timestep, testFunctionA) + 1/2*inner(dot(grad(theta),grad(theta)), testFunctionA) - inner(inner(cFunktion,theta), testFunctionA) )*dx F_onlyAdv = (inner((theta - theta_old)/timestep, testFunctionA) + inner(dot(u_adv,grad(theta)), testFunctionA) - inner(inner(cFunktion,theta), testFunctionA) )*dx F_advLap = (inner((theta - theta_old)/timestep, testFunctionA) + inner(dot(u_adv,grad(theta)), testFunctionA) + kappa * inner(grad(theta), grad(testFunctionA)) - inner(inner(cFunktion,theta), testFunctionA) )*dx if numberTestFunctions == 2: