def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.presinc.calculateJacobian( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.numericalFlux.isDOFBoundary[0], self.ebqe[('diffusiveFlux_bc_flag', 0, 0)], self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.fluidModel.timeIntegration.alpha_bdf, self.coefficients.fluidModel.q[('velocity', 0)], self.coefficients.fluidModel.coefficients.q_velocity_solid, self.coefficients.fluidModel.coefficients.q_vos, self.coefficients.fluidModel.coefficients.rho_s, self.coefficients.fluidModel.coefficients.q_rho, self.coefficients.rho_s_min, self.coefficients.rho_f_min, self.coefficients.fluidModel.ebqe[('velocity', 0)], self.coefficients.fluidModel.coefficients.ebqe_velocity_solid, self.coefficients.fluidModel.coefficients.ebqe_vos, self.coefficients.fluidModel.coefficients.ebqe_rho, self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.csrColumnOffsets_eb[(0, 0)]) if self.coefficients.fixNullSpace: dofN = 0 global_dofN = self.offset[0] + self.stride[0] * dofN for i in range(self.rowptr[global_dofN], self.rowptr[global_dofN + 1]): if (self.colind[i] == global_dofN): self.nzval[i] = 1.0 else: self.nzval[i] = 0.0 log("Jacobian ", level=10, data=jacobian) # mwf decide if this is reasonable for solver statistics self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def getResidual(self, u, r): import copy """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # set strong Dirichlet conditions for dofN, g in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.items()): # load the BC valu # Load the unknowns into the finite element dof u[self.offset[0] + self.stride[0] * dofN] = g(self.dirichletConditionsForceDOF[0].DOFBoundaryPointDict[dofN], self.timeIntegration.t) self.setUnknowns(u) if self.coefficients.pressureIncrementModelIndex is not None: coefficients_pressureIncrementModel_q_u = self.coefficients.pressureIncrementModel.q[('u', 0)] else: coefficients_pressureIncrementModel_q_u = numpy.zeros(self.q[('u', 0)].shape, 'd') # no flux boundary conditions self.pres.calculateResidual( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, # physics self.mesh.nElements_global, self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.q[('u', 0)], self.q[('grad(u)', 0)], self.q[('u_last', 0)], coefficients_pressureIncrementModel_q_u, self.coefficients.q_massFlux, self.coefficients.ebqe_massFlux, self.ebqe[('u', 0)], self.ebqe[('grad(u)', 0)], self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray) for dofN, g in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.items()): r[self.offset[0] + self.stride[0] * dofN] = self.u[0].dof[dofN] - \ g(self.dirichletConditionsForceDOF[0].DOFBoundaryPointDict[dofN], self.timeIntegration.t) log("Global residual", level=9, data=r) self.nonlinear_function_evaluations += 1
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.presinc.calculateJacobian( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.numericalFlux.isDOFBoundary[0], self.ebqe[('diffusiveFlux_bc_flag', 0, 0)], self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.fluidModel.timeIntegration.alpha_bdf, self.coefficients.fluidModel.q[('velocity', 0)], self.coefficients.fluidModel.coefficients.q_velocity_solid, self.coefficients.fluidModel.coefficients.q_vos, self.coefficients.fluidModel.coefficients.rho_s, self.coefficients.fluidModel.coefficients.q_rho, self.coefficients.rho_s_min, self.coefficients.rho_f_min, self.coefficients.fluidModel.ebqe[('velocity', 0)], self.coefficients.fluidModel.coefficients.ebqe_velocity_solid, self.coefficients.fluidModel.coefficients.ebqe_vos, self.coefficients.fluidModel.coefficients.ebqe_rho, self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.csrColumnOffsets_eb[(0, 0)]) if self.coefficients.fixNullSpace and self.comm.rank() == 0: dofN = 0 global_dofN = self.offset[0] + self.stride[0] * dofN for i in range(self.rowptr[global_dofN], self.rowptr[global_dofN + 1]): if (self.colind[i] == global_dofN): self.nzval[i] = 1.0 else: self.nzval[i] = 0.0 log("Jacobian ", level=10, data=jacobian) # mwf decide if this is reasonable for solver statistics self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def __init__(self, domain, nd=None, BC_class=None): if nd != domain.nd: log('Shape ('+`nd`+'D) and Domain ('+`domain.nd`+'D)' \ ' have different dimensions!') sys.exit() self.Domain = domain domain.shape_list.append(self) self.nd = nd self.BC_class = BC_class or bc.BC_Base self.vertices = None self.vertexFlags = None self.segments = None self.segmentFlags = None self.facets = None self.facetFlags = None self.regions = None self.regionFlags = None self.holes = None self.barycenter = np.zeros(3) self.coords = None # Only used for predefined shapes # (can be different from barycenter) self.coords_system = np.eye(nd) self.boundaryTags = None self.b_or = None # boundary orientation self.volume = None self.BC_list = []
def updateShockCapturingHistory(self): self.nSteps += 1 if self.lag: for ci in range(self.nc): self.numDiff_last[ci][:] = self.numDiff[ci] if self.lag == False and self.nStepsToDelay is not None and self.nSteps > self.nStepsToDelay: log("ADR.ShockCapturing: switched to lagged shock capturing") self.lag = True self.numDiff_last = [] for ci in range(self.nc): self.numDiff_last.append(self.numDiff[ci].copy()) log("VOF: max numDiff %e" % (globalMax(self.numDiff_last[0].max()), ))
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.presinc.calculateJacobian( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.numericalFlux.isDOFBoundary[0], self.ebqe[('advectiveFlux_bc_flag', 0)], self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.fluidModel.timeIntegration.alpha_bdf, self.coefficients.fluidModel.q[('velocity',0)], self.coefficients.fluidModel.coefficients.q_velocity_solid, self.coefficients.fluidModel.coefficients.q_vos, self.coefficients.fluidModel.coefficients.rho_s, self.coefficients.fluidModel.coefficients.q_rho, self.coefficients.rho_s_min, self.coefficients.rho_f_min, self.coefficients.fluidModel.ebqe[('velocity',0)], self.coefficients.fluidModel.coefficients.ebqe_velocity_solid, self.coefficients.fluidModel.coefficients.ebqe_vos, self.coefficients.fluidModel.coefficients.ebqe_rho, self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.csrColumnOffsets_eb[(0, 0)]) log("Jacobian ", level=10, data=jacobian) # mwf decide if this is reasonable for solver statistics self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) argsDict = cArgumentsDict.ArgumentsDict() argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi argsDict["mesh_grad_trial_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi argsDict["mesh_dof"] = self.mesh.nodeArray argsDict["mesh_l2g"] = self.mesh.elementNodesArray argsDict["dV_ref"] = self.elementQuadratureWeights[('u', 0)] argsDict["u_trial_ref"] = self.u[0].femSpace.psi argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi argsDict["u_test_ref"] = self.u[0].femSpace.psi argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi argsDict["mesh_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.psi_trace argsDict["mesh_grad_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi_trace argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u', 0)] argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals argsDict["boundaryJac_ref"] = self.u[ 0].femSpace.elementMaps.boundaryJacobians argsDict["nElements_global"] = self.mesh.nElements_global argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0, 0)] argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0, 0)] argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] self.pres.calculateJacobian(argsDict) for dofN in list(self.dirichletConditionsForceDOF[0]. DOFBoundaryConditionsDict.keys()): global_dofN = self.offset[0] + self.stride[0] * dofN self.nzval[np.where(self.colind == global_dofN)] = 0.0 # column self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN + 1]] = 0.0 # row zeroRow = True for i in range(self.rowptr[global_dofN], self.rowptr[global_dofN + 1]): # row if (self.colind[i] == global_dofN): self.nzval[i] = 1.0 zeroRow = False if zeroRow: raise RuntimeError( "Jacobian has a zero row because sparse matrix has no diagonal entry at row " + repr(global_dofN) + ". You probably need add diagonal mass or reaction term") log("Jacobian ", level=10, data=jacobian) self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def _generateMesh(domain): # --------------------------- # # ----- MESH GENERATION ----- # # --------------------------- # mesh = domain.MeshOptions if mesh.outputFiles['poly'] is True: domain.writePoly(mesh.outputFiles['name']) if mesh.outputFiles['ply'] is True: domain.writePLY(mesh.outputFiles['name']) if mesh.outputFiles['asymptote'] is True: domain.writeAsymptote(mesh.outputFiles['name']) mesh.setTriangleOptions() log("""Mesh generated using: tetgen -%s %s""" % (mesh.triangleOptions, domain.polyfile + ".poly"))
def _generateMesh(domain): # --------------------------- # # ----- MESH GENERATION ----- # # --------------------------- # mesh = domain.MeshOptions if mesh.outputFiles['poly'] is True: domain.writePoly(mesh.outputFiles['name']) if mesh.outputFiles['ply'] is True: domain.writePLY(mesh.outputFiles['name']) if mesh.outputFiles['asymptote'] is True: domain.writeAsymptote(mesh.outputFiles['name']) mesh.setTriangleOptions() log("""Mesh generated using: tetgen -%s %s""" % (mesh.triangleOptions, domain.polyfile+".poly"))
def __init__(self, coefficients, nd, shockCapturingFactor=0.25, lag=True, nStepsToDelay=None): ShockCapturing_base.__init__(self, coefficients, nd, shockCapturingFactor, lag) self.nStepsToDelay = nStepsToDelay self.nSteps = 0 if self.lag: log("ADR.ShockCapturing: lagging requested but must lag the first step; switching lagging off and delaying" ) self.nStepsToDelay = 1 self.lag = False
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) argsDict = cArgumentsDict.ArgumentsDict() argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi argsDict["mesh_grad_trial_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi argsDict["mesh_dof"] = self.mesh.nodeArray argsDict["mesh_l2g"] = self.mesh.elementNodesArray argsDict["dV_ref"] = self.elementQuadratureWeights[('u', 0)] argsDict["u_trial_ref"] = self.u[0].femSpace.psi argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi argsDict["u_test_ref"] = self.u[0].femSpace.psi argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi argsDict["mesh_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.psi_trace argsDict["mesh_grad_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi_trace argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u', 0)] argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals argsDict["boundaryJac_ref"] = self.u[ 0].femSpace.elementMaps.boundaryJacobians argsDict["nElements_global"] = self.mesh.nElements_global argsDict["useMetrics"] = self.coefficients.useMetrics argsDict["epsFactHeaviside"] = self.coefficients.epsFactHeaviside argsDict["epsFactDirac"] = self.coefficients.epsFactDirac argsDict["epsFactDiffusion"] = self.coefficients.epsFactDiffusion argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g argsDict["elementDiameter"] = self.elementDiameter argsDict["nodeDiametersArray"] = self.mesh.nodeDiametersArray argsDict["u_dof"] = self.u[0].dof argsDict["q_phi"] = self.coefficients.q_u_ls argsDict["q_normal_phi"] = self.coefficients.q_n_ls argsDict["q_H"] = self.coefficients.q_H_vof argsDict["q_vos"] = self.coefficients.q_vos argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0, 0)] argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0, 0)] argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] self.presinit.calculateJacobian(argsDict) log("Jacobian ", level=10, data=jacobian) # mwf decide if this is reasonable for solver statistics self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.pres.calculateJacobian( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian) for dofN in self.dirichletConditionsForceDOF[ 0].DOFBoundaryConditionsDict.keys(): global_dofN = self.offset[0] + self.stride[0] * dofN self.nzval[numpy.where(self.colind == global_dofN)] = 0.0 # column self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN + 1]] = 0.0 # row zeroRow = True for i in range(self.rowptr[global_dofN], self.rowptr[global_dofN + 1]): # row if (self.colind[i] == global_dofN): self.nzval[i] = 1.0 zeroRow = False if zeroRow: raise RuntimeError( "Jacobian has a zero row because sparse matrix has no diagonal entry at row " + ` global_dofN ` + ". You probably need add diagonal mass or reaction term") log("Jacobian ", level=10, data=jacobian) self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.presinit.calculateJacobian( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.coefficients.useMetrics, self.coefficients.epsFactHeaviside, self.coefficients.epsFactDirac, self.coefficients.epsFactDiffusion, self.u[0].femSpace.dofMap.l2g, self.elementDiameter, # self.mesh.elementDiametersArray, self.mesh.nodeDiametersArray, self.u[0].dof, self.coefficients.q_u_ls, self.coefficients.q_n_ls, self.coefficients.q_H_vof, self.coefficients.q_vos, self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian) log("Jacobian ", level=10, data=jacobian) # mwf decide if this is reasonable for solver statistics self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def __init__(self, shape, zone_type, center, orientation, waves, windSpeed, epsFact_solid, dragAlpha, dragBeta, porosity): self.Shape = shape self.zone_type = zone_type self.center = center self.orientation = orientation self.waves = waves self.windSpeed = windSpeed if zone_type == 'absorption' or zone_type == 'porous': self.u = self.v = self.w = lambda x, t: 0. elif zone_type == 'generation': self.u = self.setGenerationFunctions(0) self.v = self.setGenerationFunctions(1) self.w = self.setGenerationFunctions(2) else: log('Wrong zone type: ' + self.zone_type) sys.exit() self.epsFact_solid = epsFact_solid self.dragAlpha = dragAlpha self.dragBeta = dragBeta self.porosity = porosity
def getJacobian(self, jacobian): cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.pres.calculateJacobian( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian) for dofN in self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys(): global_dofN = self.offset[0] + self.stride[0] * dofN self.nzval[numpy.where(self.colind == global_dofN)] = 0.0 # column self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN + 1]] = 0.0 # row zeroRow = True for i in range(self.rowptr[global_dofN], self.rowptr[global_dofN + 1]): # row if (self.colind[i] == global_dofN): self.nzval[i] = 1.0 zeroRow = False if zeroRow: raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row " + `global_dofN`+". You probably need add diagonal mass or reaction term") log("Jacobian ", level=10, data=jacobian) self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def calculateExteriorElementBoundaryQuadrature(self): log("initalizing ebqe vectors for post-procesing velocity") self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace( self.elementBoundaryQuadraturePoints, self.ebqe['x']) self.u[0].femSpace.elementMaps.getJacobianValuesGlobalExteriorTrace( self.elementBoundaryQuadraturePoints, self.ebqe['inverse(J)'], self.ebqe['g'], self.ebqe['sqrt(det(g))'], self.ebqe['n']) cfemIntegrals.calculateIntegrationWeights( self.ebqe['sqrt(det(g))'], self.elementBoundaryQuadratureWeights[('u', 0)], self.ebqe[('dS_u', 0)]) self.u[0].femSpace.elementMaps.getBasisValuesTraceRef( self.elementBoundaryQuadraturePoints) self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef( self.elementBoundaryQuadraturePoints) self.u[0].femSpace.getBasisValuesTraceRef( self.elementBoundaryQuadraturePoints) self.u[0].femSpace.getBasisGradientValuesTraceRef( self.elementBoundaryQuadraturePoints) log("setting flux boundary conditions") self.fluxBoundaryConditionsObjectsDict = dict([ (cj, FluxBoundaryConditions( self.mesh, self.nElementBoundaryQuadraturePoints_elementBoundary, self.ebqe[('x')], self.advectiveFluxBoundaryConditionsSetterDict[cj], self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) for cj in list( self.advectiveFluxBoundaryConditionsSetterDict.keys()) ]) log("initializing coefficients ebqe") self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature( self.timeIntegration.t, self.ebqe)
def calculateExteriorElementBoundaryQuadrature(self): log("initalizing ebqe vectors for post-procesing velocity") self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, self.ebqe['x']) self.u[0].femSpace.elementMaps.getJacobianValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, self.ebqe['inverse(J)'], self.ebqe['g'], self.ebqe['sqrt(det(g))'], self.ebqe['n']) cfemIntegrals.calculateIntegrationWeights(self.ebqe['sqrt(det(g))'], self.elementBoundaryQuadratureWeights[('u', 0)], self.ebqe[('dS_u', 0)]) self.u[0].femSpace.elementMaps.getBasisValuesTraceRef( self.elementBoundaryQuadraturePoints) self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef( self.elementBoundaryQuadraturePoints) self.u[0].femSpace.getBasisValuesTraceRef( self.elementBoundaryQuadraturePoints) self.u[0].femSpace.getBasisGradientValuesTraceRef( self.elementBoundaryQuadraturePoints) log("setting flux boundary conditions") self.fluxBoundaryConditionsObjectsDict = dict([(cj, FluxBoundaryConditions(self.mesh, self.nElementBoundaryQuadraturePoints_elementBoundary, self.ebqe[('x')], self.advectiveFluxBoundaryConditionsSetterDict[cj], self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) for cj in self.advectiveFluxBoundaryConditionsSetterDict.keys()]) log("initializing coefficients ebqe") self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t, self.ebqe)
def getResidual(self, u, r): import pdb import copy from proteus.flcbdfWrappers import globalSum """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # Load the unknowns into the finite element dof self.setUnknowns(u) self.numericalFlux.setDirichletValues(self.ebqe) # flux boundary conditions for t, g in self.fluxBoundaryConditionsObjectsDict[ 0].advectiveFluxBoundaryConditionsDict.iteritems(): self.ebqe[('advectiveFlux_bc', 0)][t[0], t[1]] = g(self.ebqe[('x')][t[0], t[1]], self.timeIntegration.t) self.ebqe[('advectiveFlux_bc_flag', 0)][t[0], t[1]] = 1 for t, g in self.fluxBoundaryConditionsObjectsDict[ 0].diffusiveFluxBoundaryConditionsDictDict[0].iteritems(): self.ebqe[('diffusiveFlux_bc',0,0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) self.ebqe[('diffusiveFlux_bc_flag',0,0)][t[0],t[1]] = 1 if self.coefficients.fixNullSpace: self.u[0].dof[0] = 0 self.presinc.calculateResidual( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, # physics self.mesh.nElements_global, self.numericalFlux.isDOFBoundary[0], self.ebqe[('diffusiveFlux_bc_flag', 0, 0)], self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.fluidModel.timeIntegration.alpha_bdf, self.coefficients.fluidModel.q[('velocity', 0)], self.coefficients.fluidModel.q['divU'], self.coefficients.fluidModel.coefficients.q_velocity_solid, self.coefficients.fluidModel.coefficients.q_vos, self.coefficients.fluidModel.coefficients.rho_s, self.coefficients.fluidModel.coefficients.q_rho, self.coefficients.rho_s_min, self.coefficients.rho_f_min, self.coefficients.fluidModel.ebqe[('velocity', 0)], self.coefficients.fluidModel.coefficients.ebqe_velocity_solid, self.coefficients.fluidModel.coefficients.ebqe_vos, self.coefficients.fluidModel.coefficients.ebqe_rho, self.q[('u', 0)], self.q[('grad(u)', 0)], self.ebqe[('u', 0)], self.ebqe[('grad(u)', 0)], self.numericalFlux.ebqe[('u', 0)], self.ebqe[('advectiveFlux', 0)], self.ebqe[('diffusiveFlux', 0, 0)], self.ebqe[('advectiveFlux_bc', 0)], self.ebqe[('diffusiveFlux_bc', 0, 0)], self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.coefficients.INTEGRATE_BY_PARTS_DIV_U, self.q['a'], self.ebqe['a']) if self.coefficients.fixNullSpace: r[0] = 0. log("Global residual", level=9, data=r) # turn this on to view the global conservation residual # it should be the same as the linear solver residual tolerance # self.coefficients.massConservationError = fabs( # globalSum(r[:self.mesh.nNodes_owned].sum())) # log(" Mass Conservation Error", level=3, # data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1
def __init__(self, uDict, phiDict, testSpaceDict, matType, dofBoundaryConditionsDict, dofBoundaryConditionsSetterDict, coefficients, elementQuadrature, elementBoundaryQuadrature, fluxBoundaryConditionsDict=None, advectiveFluxBoundaryConditionsSetterDict=None, diffusiveFluxBoundaryConditionsSetterDictDict=None, stressTraceBoundaryConditionsSetterDict=None, stabilization=None, shockCapturing=None, conservativeFluxDict=None, numericalFluxType=None, TimeIntegrationClass=None, massLumping=False, reactionLumping=False, options=None, name='defaultName', reuse_trial_and_test_quadrature=True, sd=True, movingDomain=False): #, from proteus import Comm # #set the objects describing the method and boundary conditions # self.movingDomain = movingDomain self.tLast_mesh = None # self.name = name self.sd = sd self.Hess = False self.lowmem = True self.timeTerm = True #allow turning off the time derivative #self.lowmem=False self.testIsTrial = True self.phiTrialIsTrial = True self.u = uDict self.ua = {} #analytical solutions self.phi = phiDict self.dphi = {} self.matType = matType #mwf try to reuse test and trial information across components if spaces are the same self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature #True#False if self.reuse_test_trial_quadrature: for ci in range(1, coefficients.nc): assert self.u[ci].femSpace.__class__.__name__ == self.u[ 0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" ## Simplicial Mesh self.mesh = self.u[ 0].femSpace.mesh #assume the same mesh for all components for now self.testSpace = testSpaceDict self.dirichletConditions = dofBoundaryConditionsDict self.dirichletNodeSetList = None #explicit Dirichlet conditions for now, no Dirichlet BC constraints self.coefficients = coefficients self.coefficients.initializeMesh(self.mesh) self.nc = self.coefficients.nc self.stabilization = stabilization self.shockCapturing = shockCapturing self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now self.fluxBoundaryConditions = fluxBoundaryConditionsDict self.advectiveFluxBoundaryConditionsSetterDict = advectiveFluxBoundaryConditionsSetterDict self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict #determine whether the stabilization term is nonlinear self.stabilizationIsNonlinear = False #cek come back if self.stabilization is not None: for ci in range(self.nc): if coefficients.mass.has_key(ci): for flag in coefficients.mass[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.advection.has_key(ci): for flag in coefficients.advection[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.diffusion.has_key(ci): for diffusionDict in coefficients.diffusion[ci].values(): for flag in diffusionDict.values(): if flag != 'constant': self.stabilizationIsNonlinear = True if coefficients.potential.has_key(ci): for flag in coefficients.potential[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.reaction.has_key(ci): for flag in coefficients.reaction[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.hamiltonian.has_key(ci): for flag in coefficients.hamiltonian[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True #determine if we need element boundary storage self.elementBoundaryIntegrals = {} for ci in range(self.nc): self.elementBoundaryIntegrals[ci] = ( (self.conservativeFlux is not None) or (numericalFluxType is not None) or (self.fluxBoundaryConditions[ci] == 'outFlow') or (self.fluxBoundaryConditions[ci] == 'mixedFlow') or (self.fluxBoundaryConditions[ci] == 'setFlow')) # #calculate some dimensions # self.nSpace_global = self.u[ 0].femSpace.nSpace_global #assume same space dim for all variables self.nDOF_trial_element = [ u_j.femSpace.max_nDOF_element for u_j in self.u.values() ] self.nDOF_phi_trial_element = [ phi_k.femSpace.max_nDOF_element for phi_k in self.phi.values() ] self.n_phi_ip_element = [ phi_k.femSpace.referenceFiniteElement.interpolationConditions. nQuadraturePoints for phi_k in self.phi.values() ] self.nDOF_test_element = [ femSpace.max_nDOF_element for femSpace in self.testSpace.values() ] self.nFreeDOF_global = [ dc.nFreeDOF_global for dc in self.dirichletConditions.values() ] self.nVDOF_element = sum(self.nDOF_trial_element) self.nFreeVDOF_global = sum(self.nFreeDOF_global) # NonlinearEquation.__init__(self, self.nFreeVDOF_global) # #build the quadrature point dictionaries from the input (this #is just for convenience so that the input doesn't have to be #complete) # elementQuadratureDict = {} elemQuadIsDict = isinstance(elementQuadrature, dict) if elemQuadIsDict: #set terms manually for I in self.coefficients.elementIntegralKeys: if elementQuadrature.has_key(I): elementQuadratureDict[I] = elementQuadrature[I] else: elementQuadratureDict[I] = elementQuadrature['default'] else: for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[I] = elementQuadrature if self.stabilization is not None: for I in self.coefficients.elementIntegralKeys: if elemQuadIsDict: if elementQuadrature.has_key(I): elementQuadratureDict[('stab', ) + I[1:]] = elementQuadrature[I] else: elementQuadratureDict[ ('stab', ) + I[1:]] = elementQuadrature['default'] else: elementQuadratureDict[('stab', ) + I[1:]] = elementQuadrature if self.shockCapturing is not None: for ci in self.shockCapturing.components: if elemQuadIsDict: if elementQuadrature.has_key(('numDiff', ci, ci)): elementQuadratureDict[( 'numDiff', ci, ci)] = elementQuadrature[('numDiff', ci, ci)] else: elementQuadratureDict[( 'numDiff', ci, ci)] = elementQuadrature['default'] else: elementQuadratureDict[('numDiff', ci, ci)] = elementQuadrature if massLumping: for ci in self.coefficients.mass.keys(): elementQuadratureDict[( 'm', ci)] = Quadrature.SimplexLobattoQuadrature( self.nSpace_global, 1) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[ ('stab', ) + I[1:]] = Quadrature.SimplexLobattoQuadrature( self.nSpace_global, 1) if reactionLumping: for ci in self.coefficients.mass.keys(): elementQuadratureDict[( 'r', ci)] = Quadrature.SimplexLobattoQuadrature( self.nSpace_global, 1) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[ ('stab', ) + I[1:]] = Quadrature.SimplexLobattoQuadrature( self.nSpace_global, 1) elementBoundaryQuadratureDict = {} if isinstance(elementBoundaryQuadrature, dict): #set terms manually for I in self.coefficients.elementBoundaryIntegralKeys: if elementBoundaryQuadrature.has_key(I): elementBoundaryQuadratureDict[ I] = elementBoundaryQuadrature[I] else: elementBoundaryQuadratureDict[ I] = elementBoundaryQuadrature['default'] else: for I in self.coefficients.elementBoundaryIntegralKeys: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature # # find the union of all element quadrature points and # build a quadrature rule for each integral that has a # weight at each point in the union #mwf include tag telling me which indices are which quadrature rule? (self.elementQuadraturePoints, self.elementQuadratureWeights, self.elementQuadratureRuleIndeces ) = Quadrature.buildUnion(elementQuadratureDict) self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] self.nQuadraturePoints_global = self.nQuadraturePoints_element * self.mesh.nElements_global # #Repeat the same thing for the element boundary quadrature # (self.elementBoundaryQuadraturePoints, self.elementBoundaryQuadratureWeights, self.elementBoundaryQuadratureRuleIndeces ) = Quadrature.buildUnion(elementBoundaryQuadratureDict) self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[ 0] self.nElementBoundaryQuadraturePoints_global = ( self.mesh.nElements_global * self.mesh.nElementBoundaries_element * self.nElementBoundaryQuadraturePoints_elementBoundary) if type(self.u[0].femSpace) == C0_AffineLinearOnSimplexWithNodalBasis: if self.nSpace_global == 3: assert (self.nQuadraturePoints_element == 5) elif self.nSpace_global == 2: assert (self.nQuadraturePoints_element == 6) elif self.nSpace_global == 1: assert (self.nQuadraturePoints_element == 3) if self.nSpace_global == 3: assert ( self.nElementBoundaryQuadraturePoints_elementBoundary == 4) elif self.nSpace_global == 2: assert ( self.nElementBoundaryQuadraturePoints_elementBoundary == 4) elif self.nSpace_global == 1: assert ( self.nElementBoundaryQuadraturePoints_elementBoundary == 1) #pdb.set_trace() # #simplified allocations for test==trial and also check if space is mixed or not # self.q = {} self.ebq = {} self.ebq_global = {} self.ebqe = {} self.phi_ip = {} #mesh self.q['x'] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, 3), 'd') self.ebqe['x'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.q[('u', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q[('grad(u)', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global), 'd') self.q[('a', 0, 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.coefficients.sdInfo[(0, 0)][0][-1]), 'd') self.q[('df', 0, 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global), 'd') self.q[('r', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q[('cfl', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q[('numDiff', 0, 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.ebqe['penalty'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('u', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('diffusiveFlux_bc_flag', 0, 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'i') self.ebqe[('diffusiveFlux_bc', 0, 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('advectiveFlux_bc_flag', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'i') self.ebqe[('advectiveFlux_bc', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('grad(u)', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebqe[('a', 0, 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.coefficients.sdInfo[(0, 0)][0][-1]), 'd') self.ebqe[('df', 0, 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebqe[('r', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.points_elementBoundaryQuadrature = set() self.scalars_elementBoundaryQuadrature = set([ ('u', ci) for ci in range(self.nc) ]) self.vectors_elementBoundaryQuadrature = set() self.tensors_elementBoundaryQuadrature = set() log(memory("element and element boundary Jacobians", "OneLevelTransport"), level=4) self.inflowBoundaryBC = {} self.inflowBoundaryBC_values = {} self.inflowFlux = {} for cj in range(self.nc): self.inflowBoundaryBC[cj] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, ), 'i') self.inflowBoundaryBC_values[cj] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nDOF_trial_element[cj]), 'd') self.inflowFlux[cj] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.internalNodes = set(range(self.mesh.nNodes_global)) #identify the internal nodes this is ought to be in mesh ##\todo move this to mesh for ebNE in range(self.mesh.nExteriorElementBoundaries_global): ebN = self.mesh.exteriorElementBoundariesArray[ebNE] eN_global = self.mesh.elementBoundaryElementsArray[ebN, 0] ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ ebN, 0] for i in range(self.mesh.nNodes_element): if i != ebN_element: I = self.mesh.elementNodesArray[eN_global, i] self.internalNodes -= set([I]) self.nNodes_internal = len(self.internalNodes) self.internalNodesArray = numpy.zeros((self.nNodes_internal, ), 'i') for nI, n in enumerate(self.internalNodes): self.internalNodesArray[nI] = n # del self.internalNodes self.internalNodes = None log("Updating local to global mappings", 2) self.updateLocal2Global() log("Building time integration object", 2) log(memory("inflowBC, internalNodes,updateLocal2Global", "OneLevelTransport"), level=4) #mwf for interpolating subgrid error for gradients etc if self.stabilization and self.stabilization.usesGradientStabilization: self.timeIntegration = TimeIntegrationClass( self, integrateInterpolationPoints=True) else: self.timeIntegration = TimeIntegrationClass(self) if options is not None: self.timeIntegration.setFromOptions(options) log(memory("TimeIntegration", "OneLevelTransport"), level=4) log("Calculating numerical quadrature formulas", 2) self.calculateQuadrature() comm = Comm.get() self.comm = comm if comm.size() > 1: assert numericalFluxType is not None and numericalFluxType.useWeakDirichletConditions, "You must use a numerical flux to apply weak boundary conditions for parallel runs" self.setupFieldStrides() log(memory("stride+offset", "OneLevelTransport"), level=4) if numericalFluxType is not None: if options is None or options.periodicDirichletConditions is None: self.numericalFlux = numericalFluxType( self, dofBoundaryConditionsSetterDict, advectiveFluxBoundaryConditionsSetterDict, diffusiveFluxBoundaryConditionsSetterDictDict) else: self.numericalFlux = numericalFluxType( self, dofBoundaryConditionsSetterDict, advectiveFluxBoundaryConditionsSetterDict, diffusiveFluxBoundaryConditionsSetterDictDict, options.periodicDirichletConditions) else: self.numericalFlux = None #set penalty terms #cek todo move into numerical flux initialization if self.ebq_global.has_key('penalty'): for ebN in range(self.mesh.nElementBoundaries_global): for k in range( self.nElementBoundaryQuadraturePoints_elementBoundary): self.ebq_global['penalty'][ ebN, k] = self.numericalFlux.penalty_constant / ( self.mesh.elementBoundaryDiametersArray[ebN]** self.numericalFlux.penalty_power) #penalty term #cek move to Numerical flux initialization if self.ebqe.has_key('penalty'): for ebNE in range(self.mesh.nExteriorElementBoundaries_global): ebN = self.mesh.exteriorElementBoundariesArray[ebNE] for k in range( self.nElementBoundaryQuadraturePoints_elementBoundary): self.ebqe['penalty'][ ebNE, k] = self.numericalFlux.penalty_constant / self.mesh.elementBoundaryDiametersArray[ ebN]**self.numericalFlux.penalty_power log(memory("numericalFlux", "OneLevelTransport"), level=4) self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray #use post processing tools to get conservative fluxes, None by default from proteus import PostProcessingTools self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser( self) log(memory("velocity postprocessor", "OneLevelTransport"), level=4) #helper for writing out data storage from proteus import Archiver self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter( ) for ci, fbcObject in self.fluxBoundaryConditionsObjectsDict.iteritems( ): self.ebqe[('advectiveFlux_bc_flag', ci)] = numpy.zeros( self.ebqe[('advectiveFlux_bc', ci)].shape, 'i') for t, g in fbcObject.advectiveFluxBoundaryConditionsDict.iteritems( ): if self.coefficients.advection.has_key(ci): self.ebqe[('advectiveFlux_bc', ci)][t[0], t[1]] = g(self.ebqe[('x')][t[0], t[1]], self.timeIntegration.t) self.ebqe[('advectiveFlux_bc_flag', ci)][t[0], t[1]] = 1 for ck, diffusiveFluxBoundaryConditionsDict in fbcObject.diffusiveFluxBoundaryConditionsDictDict.iteritems( ): self.ebqe[('diffusiveFlux_bc_flag', ck, ci)] = numpy.zeros( self.ebqe[('diffusiveFlux_bc', ck, ci)].shape, 'i') for t, g in diffusiveFluxBoundaryConditionsDict.iteritems(): self.ebqe[('diffusiveFlux_bc', ck, ci)][t[0], t[1]] = g(self.ebqe[('x')][t[0], t[1]], self.timeIntegration.t) self.ebqe[('diffusiveFlux_bc_flag', ck, ci)][t[0], t[1]] = 1 self.numericalFlux.setDirichletValues(self.ebqe) if self.movingDomain: self.MOVING_DOMAIN = 1.0 else: self.MOVING_DOMAIN = 0.0 #cek hack self.movingDomain = False self.MOVING_DOMAIN = 0.0 if self.mesh.nodeVelocityArray is None: self.mesh.nodeVelocityArray = numpy.zeros( self.mesh.nodeArray.shape, 'd') #cek/ido todo replace python loops in modules with optimized code if possible/necessary self.forceStrongConditions = coefficients.forceStrongDirichlet self.dirichletConditionsForceDOF = {} if self.forceStrongConditions: for cj in range(self.nc): self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions( self.u[cj].femSpace, dofBoundaryConditionsSetterDict[cj], weakDirichletConditions=False) compKernelFlag = 0 self.adr = ADR( self.nSpace_global, self.nQuadraturePoints_element, self.u[0].femSpace.elementMaps.localFunctionSpace.dim, self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, self.nElementBoundaryQuadraturePoints_elementBoundary, compKernelFlag)
def getResidual(self, u, r): import pdb import copy from proteus.flcbdfWrappers import globalSum """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # Load the unknowns into the finite element dof self.setUnknowns(u) # no flux boundary conditions self.presinit.calculateResidual( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, # physics self.mesh.nElements_global, self.coefficients.useMetrics, self.coefficients.epsFactHeaviside, self.coefficients.epsFactDirac, self.coefficients.epsFactDiffusion, self.u[0].femSpace.dofMap.l2g, self.elementDiameter, # self.mesh.elementDiametersArray, self.mesh.nodeDiametersArray, self.u[0].dof, self.coefficients.q_u_ls, self.coefficients.q_n_ls, self.coefficients.ebqe_u_ls, self.coefficients.ebqe_n_ls, self.coefficients.q_H_vof, self.q[('u', 0)], self.q[('grad(u)', 0)], self.ebqe[('u', 0)], self.ebqe[('grad(u)', 0)], self.q[('r', 0)], self.coefficients.q_vos, self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray) log("Global residual", level=9, data=r) self.coefficients.massConservationError = fabs( globalSum(sum(r.flat[:self.mesh.nNodes_owned]))) assert self.coefficients.massConservationError == fabs( globalSum(r[:self.mesh.nNodes_owned].sum())) log(" Mass Conservation Error", level=3, data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1 if self.globalResidualDummy is None: self.globalResidualDummy = numpy.zeros(r.shape, 'd')
import os, sys import random import unittest import numpy.testing as npt import numpy as np from proteus import Comm, Profiling from proteus.Profiling import logEvent as log from proteus.BoundaryConditions import BC_Base from proteus.mprans.BoundaryConditions import BC_RANS comm = Comm.init() Profiling.procID = comm.rank() log("Testing BoundaryConditions") def create_BC(folder=None, b_or=None, b_i=0, nd=2): if folder is None: return BC_Base(b_or=b_or, b_i=b_i, nd=nd) if folder == 'mprans': return BC_RANS(b_or=b_or, b_i=b_i, nd=nd) def get_random_x(start=0., stop=10.): x1 = random.uniform(start, stop) x2 = random.uniform(start, stop) x3 = random.uniform(start, stop) return np.array([x1, x2, x3]) def get_time_array(start=0, stop=5, steps=100):
from proteus.Domain import (PiecewiseLinearComplexDomain, PlanarStraightLineGraphDomain) from proteus.SpatialTools import (Rectangle, Cuboid, CustomShape, assembleDomain) from proteus.mprans.SpatialTools import (Rectangle as RectangleRANS, Cuboid as CuboidRANS, CustomShape as CustomShapeRANS, assembleDomain as assembleDomainRANS, Tank2D, Tank3D, ShapeSTL) from proteus.mprans.BodyDynamics import RigidBody import pytest comm = Comm.init() Profiling.procID = comm.rank() log("Testing SpatialTools") def create_domain2D(): return PlanarStraightLineGraphDomain() def create_domain3D(): return PiecewiseLinearComplexDomain() def create_rectangle(domain, dim=(0., 0.), coords=(0., 0.), folder=None): if folder is None: return Rectangle(domain, dim, coords) elif folder == 'mprans': return RectangleRANS(domain, dim, coords)
from proteus.SpatialTools import (Rectangle, Cuboid, CustomShape, assembleDomain) from proteus.mprans.SpatialTools import (Rectangle as RectangleRANS, Cuboid as CuboidRANS, CustomShape as CustomShapeRANS, assembleDomain as assembleDomainRANS, Tank2D, Tank3D, RigidBody) comm = Comm.init() Profiling.procID = comm.rank() log("Testing SpatialTools") def create_domain2D(): return PlanarStraightLineGraphDomain() def create_domain3D(): return PiecewiseLinearComplexDomain() def create_rectangle(domain, dim=(0., 0.), coords=(0., 0.), folder=None): if folder is None: return Rectangle(domain, dim, coords) elif folder == 'mprans': return RectangleRANS(domain, dim, coords) def create_cuboid(domain, dim=(0., 0., 0.), coords=(0., 0., 0.), folder=None): if folder is None:
def getResidual(self, u, r): import pdb import copy from proteus.flcbdfWrappers import globalSum """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # set strong Dirichlet conditions for dofN, g in self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.iteritems(): # load the BC valu # Load the unknowns into the finite element dof u[self.offset[0] + self.stride[0] * dofN] = g(self.dirichletConditionsForceDOF[0].DOFBoundaryPointDict[dofN], self.timeIntegration.t) self.setUnknowns(u) if self.coefficients.pressureIncrementModelIndex is not None: coefficients_pressureIncrementModel_q_u = self.coefficients.pressureIncrementModel.q[('u', 0)] else: coefficients_pressureIncrementModel_q_u = numpy.zeros(self.q[('u', 0)].shape, 'd') # no flux boundary conditions self.pres.calculateResidual( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, # physics self.mesh.nElements_global, self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.q[('u', 0)], self.q[('grad(u)', 0)], self.q[('u_last', 0)], coefficients_pressureIncrementModel_q_u, self.coefficients.q_massFlux * (1. if self.coefficients.useRotationalForm == True else 0.), self.coefficients.ebqe_massFlux * (1. if self.coefficients.useRotationalForm == True else 0.), self.ebqe[('u', 0)], self.ebqe[('grad(u)', 0)], self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray) for dofN, g in self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.iteritems(): r[self.offset[0] + self.stride[0] * dofN] = self.u[0].dof[dofN] - \ g(self.dirichletConditionsForceDOF[0].DOFBoundaryPointDict[dofN], self.timeIntegration.t) log("Global residual", level=9, data=r) self.nonlinear_function_evaluations += 1
def getResidual(self, u, r): import pdb import copy from proteus.flcbdfWrappers import globalSum """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # Load the unknowns into the finite element dof self.setUnknowns(u) self.numericalFlux.setDirichletValues(self.ebqe) # flux boundary conditions for t, g in self.fluxBoundaryConditionsObjectsDict[ 0].advectiveFluxBoundaryConditionsDict.iteritems(): self.ebqe[ ('advectiveFlux_bc', 0)][ t[0], t[1]] = g( self.ebqe[ ('x')][ t[0], t[1]], self.timeIntegration.t) self.ebqe[('advectiveFlux_bc_flag', 0)][t[0], t[1]] = 1 for t,g in self.fluxBoundaryConditionsObjectsDict[ 0].diffusiveFluxBoundaryConditionsDictDict[0].iteritems(): self.ebqe[('diffusiveFlux_bc',0,0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) self.ebqe[('diffusiveFlux_bc_flag',0,0)][t[0],t[1]] = 1 if False:#self.forceStrongConditions: for dofN, g in self.dirichletConditionsForceDOF.DOFBoundaryConditionsDict.iteritems(): self.u[0].dof[dofN] = g( self.dirichletConditionsForceDOF.DOFBoundaryPointDict[dofN], self.timeIntegration.t) self.presinc.calculateResidual( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, # physics self.mesh.nElements_global, self.numericalFlux.isDOFBoundary[0], self.ebqe[('advectiveFlux_bc_flag', 0)], self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.fluidModel.timeIntegration.alpha_bdf, self.coefficients.fluidModel.q[('velocity',0)], self.coefficients.fluidModel.coefficients.q_velocity_solid, self.coefficients.fluidModel.coefficients.q_vos, self.coefficients.fluidModel.coefficients.rho_s, self.coefficients.fluidModel.coefficients.q_rho, self.coefficients.rho_s_min, self.coefficients.rho_f_min, self.coefficients.fluidModel.ebqe[('velocity',0)], self.coefficients.fluidModel.coefficients.ebqe_velocity_solid, self.coefficients.fluidModel.coefficients.ebqe_vos, self.coefficients.fluidModel.coefficients.ebqe_rho, self.q[('u', 0)], self.q[('grad(u)', 0)], self.ebqe[('u', 0)], self.ebqe[('grad(u)', 0)], self.numericalFlux.ebqe[('u',0)], self.ebqe[('advectiveFlux', 0)], self.ebqe[('diffusiveFlux', 0, 0)], self.ebqe[('advectiveFlux_bc', 0)], self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray) log("Global residual", level=9, data=r) self.coefficients.massConservationError = fabs( globalSum(r[:self.mesh.nNodes_owned].sum())) log(" Mass Conservation Error", level=3, data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1
import os, sys import random import unittest import numpy.testing as npt import numpy as np from proteus import Comm, Profiling from proteus.Profiling import logEvent as log from proteus.BoundaryConditions import BC_Base from proteus.mprans.BoundaryConditions import BC_RANS comm = Comm.init() Profiling.procID = comm.rank() log("Testing BoundaryConditions") def create_BC(folder=None, b_or=None, b_i=None): if folder is None: return BC_Base(b_or=b_or, b_i=b_i) if folder == 'mprans': return BC_RANS(b_or=b_or, b_i=b_i) def get_random_x(start=0., stop=10.): x1 = random.uniform(start, stop) x2 = random.uniform(start, stop) x3 = random.uniform(start, stop) return [x1, x2, x3] def get_time_array(start=0, stop=5, steps=100):
def getResidual(self, u, r): import pdb import copy """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # Load the unknowns into the finite element dof self.setUnknowns(u) # no flux boundary conditions argsDict = cArgumentsDict.ArgumentsDict() argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi argsDict["mesh_grad_trial_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi argsDict["mesh_dof"] = self.mesh.nodeArray argsDict["mesh_l2g"] = self.mesh.elementNodesArray argsDict["dV_ref"] = self.elementQuadratureWeights[('u', 0)] argsDict["u_trial_ref"] = self.u[0].femSpace.psi argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi argsDict["u_test_ref"] = self.u[0].femSpace.psi argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi argsDict["mesh_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.psi_trace argsDict["mesh_grad_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi_trace argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u', 0)] argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals argsDict["boundaryJac_ref"] = self.u[ 0].femSpace.elementMaps.boundaryJacobians argsDict["nElements_global"] = self.mesh.nElements_global argsDict["useMetrics"] = self.coefficients.useMetrics argsDict["epsFactHeaviside"] = self.coefficients.epsFactHeaviside argsDict["epsFactDirac"] = self.coefficients.epsFactDirac argsDict["epsFactDiffusion"] = self.coefficients.epsFactDiffusion argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g argsDict["elementDiameter"] = self.elementDiameter argsDict["nodeDiametersArray"] = self.mesh.nodeDiametersArray argsDict["u_dof"] = self.u[0].dof argsDict["q_phi"] = self.coefficients.q_u_ls argsDict["q_normal_phi"] = self.coefficients.q_n_ls argsDict["ebqe_phi"] = self.coefficients.ebqe_u_ls argsDict["ebqe_normal_phi"] = self.coefficients.ebqe_n_ls argsDict["q_H"] = self.coefficients.q_H_vof argsDict["q_u"] = self.q[('u', 0)] argsDict["q_n"] = self.q[('grad(u)', 0)] argsDict["ebqe_u"] = self.ebqe[('u', 0)] argsDict["ebqe_n"] = self.ebqe[('grad(u)', 0)] argsDict["q_r"] = self.q[('r', 0)] argsDict["q_vos"] = self.coefficients.q_vos argsDict["offset_u"] = self.offset[0] argsDict["stride_u"] = self.stride[0] argsDict["globalResidual"] = r argsDict[ "nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global argsDict[ "exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray argsDict[ "elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray argsDict[ "elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray self.presinit.calculateResidual(argsDict) log("Global residual", level=9, data=r) self.coefficients.massConservationError = fabs( globalSum(sum(r.flat[:self.mesh.nNodes_owned]))) assert self.coefficients.massConservationError == fabs( globalSum(r[:self.mesh.nNodes_owned].sum())) log(" Mass Conservation Error", level=3, data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1 if self.globalResidualDummy is None: self.globalResidualDummy = np.zeros(r.shape, 'd')
def getResidual(self, u, r): import pdb import copy """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # Load the unknowns into the finite element dof self.setUnknowns(u) self.numericalFlux.setDirichletValues(self.ebqe) # flux boundary conditions for t, g in list(self.fluxBoundaryConditionsObjectsDict[0]. advectiveFluxBoundaryConditionsDict.items()): self.ebqe[('advectiveFlux_bc', 0)][t[0], t[1]] = g(self.ebqe[('x')][t[0], t[1]], self.timeIntegration.t) self.ebqe[('advectiveFlux_bc_flag', 0)][t[0], t[1]] = 1 for t, g in list(self.fluxBoundaryConditionsObjectsDict[0]. diffusiveFluxBoundaryConditionsDictDict[0].items()): self.ebqe[('diffusiveFlux_bc', 0, 0)][t[0], t[1]] = g(self.ebqe[('x')][t[0], t[1]], self.timeIntegration.t) self.ebqe[('diffusiveFlux_bc_flag', 0, 0)][t[0], t[1]] = 1 if self.coefficients.fixNullSpace and self.comm.rank() == 0: self.u[0].dof[0] = 0 self.presinc.calculateResidual( # element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, # element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, # physics self.mesh.nElements_global, self.numericalFlux.isDOFBoundary[0], self.ebqe[('diffusiveFlux_bc_flag', 0, 0)], self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.fluidModel.timeIntegration.alpha_bdf, self.coefficients.fluidModel.q[('velocity', 0)], self.coefficients.fluidModel.q['divU'], self.coefficients.fluidModel.coefficients.q_velocity_solid, self.coefficients.fluidModel.coefficients.q_vos, self.coefficients.fluidModel.coefficients.rho_s, self.coefficients.fluidModel.coefficients.q_rho, self.coefficients.rho_s_min, self.coefficients.rho_f_min, self.coefficients.fluidModel.ebqe[('velocity', 0)], self.coefficients.fluidModel.coefficients.ebqe_velocity_solid, self.coefficients.fluidModel.coefficients.ebqe_vos, self.coefficients.fluidModel.coefficients.ebqe_rho, self.q[('u', 0)], self.q[('grad(u)', 0)], self.ebqe[('u', 0)], self.ebqe[('grad(u)', 0)], self.numericalFlux.ebqe[('u', 0)], self.ebqe[('advectiveFlux', 0)], self.ebqe[('diffusiveFlux', 0, 0)], self.ebqe[('advectiveFlux_bc', 0)], self.ebqe[('diffusiveFlux_bc', 0, 0)], self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.coefficients.INTEGRATE_BY_PARTS_DIV_U, self.q['a'], self.ebqe['a']) if self.coefficients.fixNullSpace and self.comm.rank() == 0: r[0] = 0. log("Global residual", level=9, data=r) # turn this on to view the global conservation residual # it should be the same as the linear solver residual tolerance # self.coefficients.massConservationError = fabs( # globalSum(r[:self.mesh.nNodes_owned].sum())) # log(" Mass Conservation Error", level=3, # data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1
def __init__(self, uDict, phiDict, testSpaceDict, matType, dofBoundaryConditionsDict, dofBoundaryConditionsSetterDict, coefficients, elementQuadrature, elementBoundaryQuadrature, fluxBoundaryConditionsDict=None, advectiveFluxBoundaryConditionsSetterDict=None, diffusiveFluxBoundaryConditionsSetterDictDict=None, stressTraceBoundaryConditionsSetterDict=None, stabilization=None, shockCapturing=None, conservativeFluxDict=None, numericalFluxType=None, TimeIntegrationClass=None, massLumping=False, reactionLumping=False, options=None, name='defaultName', reuse_trial_and_test_quadrature=True, sd=True, movingDomain=False, bdyNullSpace=False): self.bdyNullSpace=bdyNullSpace self.useConstantH = False#coefficients.useConstantH from proteus import Comm # # set the objects describing the method and boundary conditions # self.movingDomain = movingDomain self.tLast_mesh = None # self.name = name self.sd = sd self.Hess = False self.lowmem = True self.timeTerm = True # allow turning off the time derivative # self.lowmem=False self.testIsTrial = True self.phiTrialIsTrial = True self.u = uDict self.ua = {} # analytical solutions self.phi = phiDict self.dphi = {} self.matType = matType # mwf try to reuse test and trial information across components if # spaces are the same self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature # True#False if self.reuse_test_trial_quadrature: for ci in range(1, coefficients.nc): assert self.u[ci].femSpace.__class__.__name__ == self.u[ 0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" # Simplicial Mesh # assume the same mesh for all components for now self.mesh = self.u[0].femSpace.mesh self.testSpace = testSpaceDict self.dirichletConditions = dofBoundaryConditionsDict # explicit Dirichlet conditions for now, no Dirichlet BC constraints self.dirichletNodeSetList = None self.coefficients = coefficients self.coefficients.initializeMesh(self.mesh) self.nc = self.coefficients.nc self.stabilization = stabilization self.shockCapturing = shockCapturing # no velocity post-processing for now self.conservativeFlux = conservativeFluxDict self.fluxBoundaryConditions = fluxBoundaryConditionsDict self.advectiveFluxBoundaryConditionsSetterDict = advectiveFluxBoundaryConditionsSetterDict self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict # determine whether the stabilization term is nonlinear self.stabilizationIsNonlinear = False # cek come back if self.stabilization is not None: for ci in range(self.nc): if coefficients.mass.has_key(ci): for flag in coefficients.mass[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.advection.has_key(ci): for flag in coefficients.advection[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.diffusion.has_key(ci): for diffusionDict in coefficients.diffusion[ci].values(): for flag in diffusionDict.values(): if flag != 'constant': self.stabilizationIsNonlinear = True if coefficients.potential.has_key(ci): for flag in coefficients.potential[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.reaction.has_key(ci): for flag in coefficients.reaction[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if coefficients.hamiltonian.has_key(ci): for flag in coefficients.hamiltonian[ci].values(): if flag == 'nonlinear': self.stabilizationIsNonlinear = True # determine if we need element boundary storage self.elementBoundaryIntegrals = {} for ci in range(self.nc): self.elementBoundaryIntegrals[ci] = ( (self.conservativeFlux is not None) or ( numericalFluxType is not None) or ( self.fluxBoundaryConditions[ci] == 'outFlow') or ( self.fluxBoundaryConditions[ci] == 'mixedFlow') or ( self.fluxBoundaryConditions[ci] == 'setFlow')) # # calculate some dimensions # # assume same space dim for all variables self.nSpace_global = self.u[0].femSpace.nSpace_global self.nDOF_trial_element = [ u_j.femSpace.max_nDOF_element for u_j in self.u.values()] self.nDOF_phi_trial_element = [ phi_k.femSpace.max_nDOF_element for phi_k in self.phi.values()] self.n_phi_ip_element = [ phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in self.phi.values()] self.nDOF_test_element = [ femSpace.max_nDOF_element for femSpace in self.testSpace.values()] self.nFreeDOF_global = [ dc.nFreeDOF_global for dc in self.dirichletConditions.values()] self.nVDOF_element = sum(self.nDOF_trial_element) self.nFreeVDOF_global = sum(self.nFreeDOF_global) # NonlinearEquation.__init__(self, self.nFreeVDOF_global) # # build the quadrature point dictionaries from the input (this # is just for convenience so that the input doesn't have to be # complete) # elementQuadratureDict = {} elemQuadIsDict = isinstance(elementQuadrature, dict) if elemQuadIsDict: # set terms manually for I in self.coefficients.elementIntegralKeys: if elementQuadrature.has_key(I): elementQuadratureDict[I] = elementQuadrature[I] else: elementQuadratureDict[I] = elementQuadrature['default'] else: for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[I] = elementQuadrature if self.stabilization is not None: for I in self.coefficients.elementIntegralKeys: if elemQuadIsDict: if elementQuadrature.has_key(I): elementQuadratureDict[ ('stab',) + I[1:]] = elementQuadrature[I] else: elementQuadratureDict[ ('stab',) + I[1:]] = elementQuadrature['default'] else: elementQuadratureDict[ ('stab',) + I[1:]] = elementQuadrature if self.shockCapturing is not None: for ci in self.shockCapturing.components: if elemQuadIsDict: if elementQuadrature.has_key(('numDiff', ci, ci)): elementQuadratureDict[('numDiff', ci, ci)] = elementQuadrature[ ('numDiff', ci, ci)] else: elementQuadratureDict[('numDiff', ci, ci)] = elementQuadrature[ 'default'] else: elementQuadratureDict[ ('numDiff', ci, ci)] = elementQuadrature if massLumping: for ci in self.coefficients.mass.keys(): elementQuadratureDict[('m', ci)] = Quadrature.SimplexLobattoQuadrature( self.nSpace_global, 1) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[ ('stab',) + I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global, 1) if reactionLumping: for ci in self.coefficients.mass.keys(): elementQuadratureDict[('r', ci)] = Quadrature.SimplexLobattoQuadrature( self.nSpace_global, 1) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[ ('stab',) + I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global, 1) elementBoundaryQuadratureDict = {} if isinstance(elementBoundaryQuadrature, dict): # set terms manually for I in self.coefficients.elementBoundaryIntegralKeys: if elementBoundaryQuadrature.has_key(I): elementBoundaryQuadratureDict[ I] = elementBoundaryQuadrature[I] else: elementBoundaryQuadratureDict[ I] = elementBoundaryQuadrature['default'] else: for I in self.coefficients.elementBoundaryIntegralKeys: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature # # find the union of all element quadrature points and # build a quadrature rule for each integral that has a # weight at each point in the union # mwf include tag telling me which indices are which quadrature rule? (self.elementQuadraturePoints, self.elementQuadratureWeights, self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] self.nQuadraturePoints_global = self.nQuadraturePoints_element * \ self.mesh.nElements_global # # Repeat the same thing for the element boundary quadrature # (self.elementBoundaryQuadraturePoints, self.elementBoundaryQuadratureWeights, self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[ 0] self.nElementBoundaryQuadraturePoints_global = ( self.mesh.nElements_global * self.mesh.nElementBoundaries_element * self.nElementBoundaryQuadraturePoints_elementBoundary) if type(self.u[0].femSpace) == C0_AffineLinearOnSimplexWithNodalBasis: # print self.nQuadraturePoints_element if self.nSpace_global == 3: assert(self.nQuadraturePoints_element == 5) elif self.nSpace_global == 2: assert(self.nQuadraturePoints_element == 6) elif self.nSpace_global == 1: assert(self.nQuadraturePoints_element == 3) # print self.nElementBoundaryQuadraturePoints_elementBoundary if self.nSpace_global == 3: assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) elif self.nSpace_global == 2: assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) elif self.nSpace_global == 1: assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) # pdb.set_trace() # # simplified allocations for test==trial and also check if space is mixed or not # self.q = {} self.ebq = {} self.ebq_global = {} self.ebqe = {} self.phi_ip = {} # mesh self.q['x'] = numpy.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') self.ebqe['x'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.q[('u', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q[ ('grad(u)', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global), 'd') self.q[('r', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.ebqe[ ('u', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[ ('grad(u)', 0)] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.points_elementBoundaryQuadrature = set() self.scalars_elementBoundaryQuadrature = set( [('u', ci) for ci in range(self.nc)]) self.vectors_elementBoundaryQuadrature = set() self.tensors_elementBoundaryQuadrature = set() log(memory("element and element boundary Jacobians", "OneLevelTransport"), level=4) self.inflowBoundaryBC = {} self.inflowBoundaryBC_values = {} self.inflowFlux = {} for cj in range(self.nc): self.inflowBoundaryBC[cj] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global,), 'i') self.inflowBoundaryBC_values[cj] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nDOF_trial_element[cj]), 'd') self.inflowFlux[cj] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.internalNodes = set(range(self.mesh.nNodes_global)) # identify the internal nodes this is ought to be in mesh # \todo move this to mesh for ebNE in range(self.mesh.nExteriorElementBoundaries_global): ebN = self.mesh.exteriorElementBoundariesArray[ebNE] eN_global = self.mesh.elementBoundaryElementsArray[ebN, 0] ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ ebN, 0] for i in range(self.mesh.nNodes_element): if i != ebN_element: I = self.mesh.elementNodesArray[eN_global, i] self.internalNodes -= set([I]) self.nNodes_internal = len(self.internalNodes) self.internalNodesArray = numpy.zeros((self.nNodes_internal,), 'i') for nI, n in enumerate(self.internalNodes): self.internalNodesArray[nI] = n # del self.internalNodes self.internalNodes = None log("Updating local to global mappings", 2) self.updateLocal2Global() log("Building time integration object", 2) log(memory("inflowBC, internalNodes,updateLocal2Global", "OneLevelTransport"), level=4) # mwf for interpolating subgrid error for gradients etc if self.stabilization and self.stabilization.usesGradientStabilization: self.timeIntegration = TimeIntegrationClass( self, integrateInterpolationPoints=True) else: self.timeIntegration = TimeIntegrationClass(self) if options is not None: self.timeIntegration.setFromOptions(options) log(memory("TimeIntegration", "OneLevelTransport"), level=4) log("Calculating numerical quadrature formulas", 2) self.calculateQuadrature() self.setupFieldStrides() comm = Comm.get() self.comm = comm if comm.size() > 1: assert numericalFluxType is not None and numericalFluxType.useWeakDirichletConditions, "You must use a numerical flux to apply weak boundary conditions for parallel runs" log(memory("stride+offset", "OneLevelTransport"), level=4) if numericalFluxType is not None: if options is None or options.periodicDirichletConditions is None: self.numericalFlux = numericalFluxType( self, dofBoundaryConditionsSetterDict, advectiveFluxBoundaryConditionsSetterDict, diffusiveFluxBoundaryConditionsSetterDictDict) else: self.numericalFlux = numericalFluxType( self, dofBoundaryConditionsSetterDict, advectiveFluxBoundaryConditionsSetterDict, diffusiveFluxBoundaryConditionsSetterDictDict, options.periodicDirichletConditions) else: self.numericalFlux = None # set penalty terms # cek todo move into numerical flux initialization if self.ebq_global.has_key('penalty'): for ebN in range(self.mesh.nElementBoundaries_global): for k in range( self.nElementBoundaryQuadraturePoints_elementBoundary): self.ebq_global['penalty'][ebN, k] = self.numericalFlux.penalty_constant / ( self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) # penalty term # cek move to Numerical flux initialization if self.ebqe.has_key('penalty'): for ebNE in range(self.mesh.nExteriorElementBoundaries_global): ebN = self.mesh.exteriorElementBoundariesArray[ebNE] for k in range( self.nElementBoundaryQuadraturePoints_elementBoundary): self.ebqe['penalty'][ebNE, k] = self.numericalFlux.penalty_constant / \ self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power log(memory("numericalFlux", "OneLevelTransport"), level=4) self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray # use post processing tools to get conservative fluxes, None by default from proteus import PostProcessingTools self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser( self) log(memory("velocity postprocessor", "OneLevelTransport"), level=4) # helper for writing out data storage from proteus import Archiver self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() self.globalResidualDummy = None compKernelFlag = 0 # if self.coefficients.useConstantH: # self.elementDiameter = self.mesh.elementDiametersArray.copy() # self.elementDiameter[:] = max(self.mesh.elementDiametersArray) # else: # self.elementDiameter = self.mesh.elementDiametersArray self.elementDiameter = self.mesh.elementDiametersArray self.presinit = cPresInit.PresInit( self.nSpace_global, self.nQuadraturePoints_element, self.u[0].femSpace.elementMaps.localFunctionSpace.dim, self .u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, self.nElementBoundaryQuadraturePoints_elementBoundary, compKernelFlag)
def getResidual(self, u, r): import pdb import copy """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) #Load the unknowns into the finite element dof self.setUnknowns(u) #no flux boundary conditions self.adr.calculateResidual( #element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.mesh.elementDiametersArray, self.q[('cfl', 0)], self.shockCapturing.shockCapturingFactor, self.coefficients.sc_uref, self.coefficients.sc_beta, self.coefficients.useMetrics, #element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, #physics self.mesh.nElements_global, self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.sdInfo[(0, 0)][0], self.coefficients.sdInfo[(0, 0)][1], self.q[('a', 0, 0)], self.q[('df', 0, 0)], self.q[('r', 0)], self.shockCapturing.lag, self.shockCapturing.shockCapturingFactor, self.shockCapturing.numDiff[0], self.shockCapturing.numDiff_last[0], self.offset[0], self.stride[0], r, self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.ebqe[('a', 0, 0)], self.ebqe[('df', 0, 0)], self.numericalFlux.isDOFBoundary[0], self.numericalFlux.ebqe[('u', 0)], self.ebqe[('diffusiveFlux_bc_flag', 0, 0)], self.ebqe[('advectiveFlux_bc_flag', 0)], self.ebqe[('diffusiveFlux_bc', 0, 0)], self.ebqe[('advectiveFlux_bc', 0)], self.ebqe['penalty'], self.numericalFlux.boundaryAdjoint_sigma) log("Global residual", level=9, data=r) self.coefficients.massConservationError = fabs( globalSum(sum(r.flat[:self.mesh.nElements_owned]))) log(" Mass Conservation Error", level=3, data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1
def getResidual(self, u, r): import copy """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) # set strong Dirichlet conditions for dofN, g in list(self.dirichletConditionsForceDOF[0]. DOFBoundaryConditionsDict.items()): # load the BC valu # Load the unknowns into the finite element dof u[self.offset[0] + self.stride[0] * dofN] = g( self.dirichletConditionsForceDOF[0].DOFBoundaryPointDict[dofN], self.timeIntegration.t) self.setUnknowns(u) if self.coefficients.pressureIncrementModelIndex is not None: coefficients_pressureIncrementModel_q_u = self.coefficients.pressureIncrementModel.q[ ('u', 0)] else: coefficients_pressureIncrementModel_q_u = np.zeros( self.q[('u', 0)].shape, 'd') # no flux boundary conditions argsDict = cArgumentsDict.ArgumentsDict() argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi argsDict["mesh_grad_trial_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi argsDict["mesh_dof"] = self.mesh.nodeArray argsDict["mesh_l2g"] = self.mesh.elementNodesArray argsDict["dV_ref"] = self.elementQuadratureWeights[('u', 0)] argsDict["u_trial_ref"] = self.u[0].femSpace.psi argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi argsDict["u_test_ref"] = self.u[0].femSpace.psi argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi argsDict["mesh_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.psi_trace argsDict["mesh_grad_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi_trace argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u', 0)] argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals argsDict["boundaryJac_ref"] = self.u[ 0].femSpace.elementMaps.boundaryJacobians argsDict["nElements_global"] = self.mesh.nElements_global argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g argsDict["u_dof"] = self.u[0].dof argsDict["q_u"] = self.q[('u', 0)] argsDict["q_grad_u"] = self.q[('grad(u)', 0)] argsDict["q_p_last"] = self.q[('u_last', 0)] argsDict["q_p_inc"] = coefficients_pressureIncrementModel_q_u argsDict["q_massFlux"] = self.coefficients.q_massFlux argsDict["ebqe_massFlux"] = self.coefficients.ebqe_massFlux argsDict["ebqe_u"] = self.ebqe[('u', 0)] argsDict["ebqe_grad_u"] = self.ebqe[('grad(u)', 0)] argsDict["offset_u"] = self.offset[0] argsDict["stride_u"] = self.stride[0] argsDict["globalResidual"] = r argsDict[ "nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global argsDict[ "exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray argsDict[ "elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray argsDict[ "elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray self.pres.calculateResidual(argsDict) for dofN, g in list(self.dirichletConditionsForceDOF[0]. DOFBoundaryConditionsDict.items()): r[self.offset[0] + self.stride[0] * dofN] = self.u[0].dof[dofN] - \ g(self.dirichletConditionsForceDOF[0].DOFBoundaryPointDict[dofN], self.timeIntegration.t) log("Global residual", level=9, data=r) self.nonlinear_function_evaluations += 1
def getJacobian(self, jacobian): #import superluWrappers #import numpy import pdb cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) argsDict = cArgumentsDict.ArgumentsDict() argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi argsDict["mesh_grad_trial_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi argsDict["mesh_dof"] = self.mesh.nodeArray argsDict["mesh_l2g"] = self.mesh.elementNodesArray argsDict["dV_ref"] = self.elementQuadratureWeights[('u', 0)] argsDict["u_trial_ref"] = self.u[0].femSpace.psi argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi argsDict["u_test_ref"] = self.u[0].femSpace.psi argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi argsDict["elementDiameter"] = self.mesh.elementDiametersArray argsDict["cfl"] = self.q[('cfl', 0)] argsDict["Ct_sge"] = self.shockCapturing.shockCapturingFactor argsDict["sc_uref"] = self.coefficients.sc_uref argsDict["sc_alpha"] = self.coefficients.sc_beta argsDict["useMetrics"] = self.coefficients.useMetrics argsDict["mesh_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.psi_trace argsDict["mesh_grad_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi_trace argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u', 0)] argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals argsDict["boundaryJac_ref"] = self.u[ 0].femSpace.elementMaps.boundaryJacobians argsDict["nElements_global"] = self.mesh.nElements_global argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g argsDict["u_dof"] = self.u[0].dof argsDict["sd_rowptr"] = self.coefficients.sdInfo[(0, 0)][0] argsDict["sd_colind"] = self.coefficients.sdInfo[(0, 0)][1] argsDict["q_a"] = self.q[('a', 0, 0)] argsDict["q_v"] = self.q[('df', 0, 0)] argsDict["q_r"] = self.q[('r', 0)] argsDict["lag_shockCapturing"] = self.shockCapturing.lag argsDict[ "shockCapturingDiffusion"] = self.shockCapturing.shockCapturingFactor argsDict["q_numDiff_u"] = self.shockCapturing.numDiff[0] argsDict["q_numDiff_u_last"] = self.shockCapturing.numDiff_last[0] argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0, 0)] argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0, 0)] argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] argsDict[ "nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global argsDict[ "exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray argsDict[ "elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray argsDict[ "elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray argsDict["ebqe_a"] = self.ebqe[('a', 0, 0)] argsDict["ebqe_v"] = self.ebqe[('df', 0, 0)] argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u', 0)] argsDict["isDiffusiveFluxBoundary_u"] = self.ebqe[( 'diffusiveFlux_bc_flag', 0, 0)] argsDict["isAdvectiveFluxBoundary_u"] = self.ebqe[( 'advectiveFlux_bc_flag', 0)] argsDict["ebqe_bc_flux_u_ext"] = self.ebqe[('diffusiveFlux_bc', 0, 0)] argsDict["ebqe_bc_advectiveFlux_u_ext"] = self.ebqe[( 'advectiveFlux_bc', 0)] argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0, 0)] argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] argsDict["eb_adjoint_sigma"] = self.numericalFlux.boundaryAdjoint_sigma argsDict["embeddedBoundary"] = self.coefficients.embeddedBoundary argsDict[ "embeddedBoundary_penalty"] = self.coefficients.embeddedBoundary_penalty argsDict[ "embeddedBoundary_ghost_penalty"] = self.coefficients.embeddedBoundary_ghost_penalty argsDict[ "embeddedBoundary_sdf_nodes"] = self.coefficients.embeddedBoundary_sdf_nodes argsDict["embeddedBoundary_sdf"] = self.q['embeddedBoundary_sdf'] argsDict["embeddedBoundary_normal"] = self.q['embeddedBoundary_normal'] argsDict["embeddedBoundary_u"] = self.q['embeddedBoundary_u'] argsDict["isActiveDOF"] = self.isActiveDOF self.adr.calculateJacobian(argsDict) log("Jacobian ", level=10, data=jacobian) self.nonlinear_function_jacobian_evaluations += 1 for global_dofN_a in np.argwhere(self.isActiveDOF == 0.0): global_dofN = global_dofN_a[0] for i in range(self.rowptr[global_dofN], self.rowptr[global_dofN + 1]): if (self.colind[i] == global_dofN): self.nzval[i] = 1.0 else: self.nzval[i] = 0.0 return jacobian
def getJacobian(self, jacobian): #import superluWrappers #import numpy import pdb cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, jacobian) self.adr.calculateJacobian( #element self.u[0].femSpace.elementMaps.psi, self.u[0].femSpace.elementMaps.grad_psi, self.mesh.nodeArray, self.mesh.elementNodesArray, self.elementQuadratureWeights[('u', 0)], self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.u[0].femSpace.psi, self.u[0].femSpace.grad_psi, self.mesh.elementDiametersArray, self.q[('cfl', 0)], self.shockCapturing.shockCapturingFactor, self.coefficients.sc_uref, self.coefficients.sc_beta, self.coefficients.useMetrics, #element boundary self.u[0].femSpace.elementMaps.psi_trace, self.u[0].femSpace.elementMaps.grad_psi_trace, self.elementBoundaryQuadratureWeights[('u', 0)], self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.psi_trace, self.u[0].femSpace.grad_psi_trace, self.u[0].femSpace.elementMaps.boundaryNormals, self.u[0].femSpace.elementMaps.boundaryJacobians, self.mesh.nElements_global, self.u[0].femSpace.dofMap.l2g, self.u[0].dof, self.coefficients.sdInfo[(0, 0)][0], self.coefficients.sdInfo[(0, 0)][1], self.q[('a', 0, 0)], self.q[('df', 0, 0)], self.q[('r', 0)], self.shockCapturing.lag, self.shockCapturing.shockCapturingFactor, self.shockCapturing.numDiff[0], self.shockCapturing.numDiff_last[0], self.csrRowIndeces[(0, 0)], self.csrColumnOffsets[(0, 0)], jacobian.getCSRrepresentation()[2], self.mesh.nExteriorElementBoundaries_global, self.mesh.exteriorElementBoundariesArray, self.mesh.elementBoundaryElementsArray, self.mesh.elementBoundaryLocalElementBoundariesArray, self.ebqe[('a', 0, 0)], self.ebqe[('df', 0, 0)], self.numericalFlux.isDOFBoundary[0], self.numericalFlux.ebqe[('u', 0)], self.ebqe[('diffusiveFlux_bc_flag', 0, 0)], self.ebqe[('advectiveFlux_bc_flag', 0)], self.ebqe[('diffusiveFlux_bc', 0, 0)], self.ebqe[('advectiveFlux_bc', 0)], self.csrColumnOffsets_eb[(0, 0)], self.ebqe['penalty'], self.numericalFlux.boundaryAdjoint_sigma) log("Jacobian ", level=10, data=jacobian) #mwf decide if this is reasonable for solver statistics self.nonlinear_function_jacobian_evaluations += 1 return jacobian
def getResidual(self, u, r): import pdb import copy """ Calculate the element residuals and add in to the global residual """ r.fill(0.0) try: self.isActiveDOF[:] = 0.0 except AttributeError: self.isActiveDOF = np.zeros_like(r) #Load the unknowns into the finite element dof self.setUnknowns(u) #no flux boundary conditions argsDict = cArgumentsDict.ArgumentsDict() argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi argsDict["mesh_grad_trial_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi argsDict["mesh_dof"] = self.mesh.nodeArray argsDict["mesh_l2g"] = self.mesh.elementNodesArray argsDict["dV_ref"] = self.elementQuadratureWeights[('u', 0)] argsDict["u_trial_ref"] = self.u[0].femSpace.psi argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi argsDict["u_test_ref"] = self.u[0].femSpace.psi argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi argsDict["elementDiameter"] = self.mesh.elementDiametersArray argsDict["cfl"] = self.q[('cfl', 0)] argsDict["Ct_sge"] = self.shockCapturing.shockCapturingFactor argsDict["sc_uref"] = self.coefficients.sc_uref argsDict["sc_alpha"] = self.coefficients.sc_beta argsDict["useMetrics"] = self.coefficients.useMetrics argsDict["mesh_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.psi_trace argsDict["mesh_grad_trial_trace_ref"] = self.u[ 0].femSpace.elementMaps.grad_psi_trace argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u', 0)] argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals argsDict["boundaryJac_ref"] = self.u[ 0].femSpace.elementMaps.boundaryJacobians argsDict["nElements_global"] = self.mesh.nElements_global argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g argsDict["u_dof"] = self.u[0].dof argsDict["sd_rowptr"] = self.coefficients.sdInfo[(0, 0)][0] argsDict["sd_colind"] = self.coefficients.sdInfo[(0, 0)][1] argsDict["q_a"] = self.q[('a', 0, 0)] argsDict["q_v"] = self.q[('df', 0, 0)] argsDict["q_r"] = self.q[('r', 0)] argsDict["lag_shockCapturing"] = self.shockCapturing.lag argsDict[ "shockCapturingDiffusion"] = self.shockCapturing.shockCapturingFactor argsDict["q_numDiff_u"] = self.shockCapturing.numDiff[0] argsDict["q_numDiff_u_last"] = self.shockCapturing.numDiff_last[0] argsDict["offset_u"] = self.offset[0] argsDict["stride_u"] = self.stride[0] argsDict["globalResidual"] = r argsDict[ "nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global argsDict[ "exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray argsDict[ "elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray argsDict[ "elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray argsDict["ebqe_a"] = self.ebqe[('a', 0, 0)] argsDict["ebqe_v"] = self.ebqe[('df', 0, 0)] argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u', 0)] argsDict["isDiffusiveFluxBoundary_u"] = self.ebqe[( 'diffusiveFlux_bc_flag', 0, 0)] argsDict["isAdvectiveFluxBoundary_u"] = self.ebqe[( 'advectiveFlux_bc_flag', 0)] argsDict["ebqe_bc_flux_u_ext"] = self.ebqe[('diffusiveFlux_bc', 0, 0)] argsDict["ebqe_bc_advectiveFlux_u_ext"] = self.ebqe[( 'advectiveFlux_bc', 0)] argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] argsDict["eb_adjoint_sigma"] = self.numericalFlux.boundaryAdjoint_sigma argsDict["embeddedBoundary"] = self.coefficients.embeddedBoundary argsDict[ "embeddedBoundary_penalty"] = self.coefficients.embeddedBoundary_penalty argsDict[ "embeddedBoundary_ghost_penalty"] = self.coefficients.embeddedBoundary_ghost_penalty argsDict[ "embeddedBoundary_sdf_nodes"] = self.coefficients.embeddedBoundary_sdf_nodes argsDict["embeddedBoundary_sdf"] = self.q['embeddedBoundary_sdf'] argsDict["embeddedBoundary_normal"] = self.q['embeddedBoundary_normal'] argsDict["embeddedBoundary_u"] = self.q['embeddedBoundary_u'] argsDict["isActiveDOF"] = self.isActiveDOF self.adr.calculateResidual(argsDict) self.u[0].dof[:] = np.where(self.isActiveDOF == 1.0, self.u[0].dof, 0.0) r *= self.isActiveDOF log("Global residual", level=9, data=r) self.coefficients.massConservationError = fabs( globalSum(sum(r.flat[:self.mesh.nElements_owned]))) log(" Mass Conservation Error", level=3, data=self.coefficients.massConservationError) self.nonlinear_function_evaluations += 1