def ex4(N, hk): r""" Compute the integral of :math:`x` over the reference triangle Parameters ---------- N : int Order of base quadrature rule hk : double submesh element diameter """ quad = Quadrature.GaussTetrahedron(N) comp_quad = Quadrature.CompositeTetrahedron(quad, hk) quad_points = np.asarray(quad.points, 'd') quad_weights = np.asarray(quad.weights, 'd') ii_quad = np.sum(quad_weights * quad_points[:, 0]) ii_comp_quad = np.sum(comp_quad.weights * comp_quad.points[:, 0]) ee = np.abs(ii_quad - ii_comp_quad) logEvent("hk=%f\t quad-int=%f\t comp-quad-int=%f error=%f" % (comp_quad.h, ii_quad, ii_comp_quad, ee)) return comp_quad.h, ee
def ex3(N, hk, r0): r""" Compute the integral of :math:`1_{|[x,y]|<= r0}` :math: `r0<=0.5*sqrt(2)` Parameters ---------- N : int Order of base quadrature rule hk : double submesh element diameter r0 : integrand parameter """ quad = Quadrature.GaussTriangle(N) comp_quad = Quadrature.CompositeTriangle(quad, hk) N = int(np.ceil(old_div(1, hk))) ii = np.sum(comp_quad.weights[np.less_equal( comp_quad.points[:, 0]**2 + comp_quad.points[:, 1]**2, r0 * r0)]) ee = np.abs(ii - r0**2 * 0.25 * np.pi) logEvent("hk=%f\t true-int=%f\t comp-int=%f error=%f" % (old_div(1.0, N), r0**2 * 0.25 * np.pi, ii, ee)) return old_div(1.0, N), ee
def ex2(N, hk, x0=1, y0=1, z0=1): r""" Compute the integral of :math:`1_{x/x0+y/y0+z/z0<= 1}` :math:`0< x0\leq 1` and :math:`0< y0\leq 1` and :math:`0< z0\leq 1` Parameters ---------- N : int Order of base quadrature rule hk : double submesh element diameter x0 : integrand parameter y0 : integrand parameter z0 : integrand parameter """ quad = Quadrature.GaussTetrahedron(N) comp_quad = Quadrature.CompositeTetrahedron(quad, hk) ii = np.sum(comp_quad.weights[np.less_equal( old_div(comp_quad.points[:, 0], x0) + old_div(comp_quad.points[:, 1], y0) + old_div(+comp_quad.points[:, 2], z0), 1.0)]) ee = np.abs(ii - x0 * y0 * z0 / 6.0) logEvent("hk=%f\t true-int=%f\t comp-int=%f error=%f" % (comp_quad.h, x0 * y0 * z0 / 6.0, ii, ee)) return comp_quad.h, ee
def ex6(N, hk): r""" Compute the integral of :math:`x*y*y` over the reference triangle Parameters ---------- N : int Order of base quadrature rule hk : double submesh element diameter """ quad = Quadrature.GaussTriangle(N) comp_quad = Quadrature.CompositeTriangle(quad, hk) N = int(np.ceil(old_div(1, hk))) quad_points = np.asarray(quad.points, 'd') quad_weights = np.asarray(quad.weights, 'd') ii_quad = np.sum(quad_weights * quad_points[:, 0] * quad_points[:, 1] * quad_points[:, 1]) ii_comp_quad = np.sum(comp_quad.weights * comp_quad.points[:, 0] * comp_quad.points[:, 1] * comp_quad.points[:, 1]) ee = np.abs(ii_quad - ii_comp_quad) logEvent("hk=%f\t quad-int=%f\t comp-quad-int=%f error=%f" % (old_div(1.0, N), ii_quad, ii_comp_quad, ee)) return old_div(1.0, N), ee
def ex2(N, hk, x0, y0): r""" Compute the integral of :math:`1_{x0*y+y0*x<= x0*y0}` :math:`0\leqx0\leq1` and :math:`0\leqy0\leq1` Parameters ---------- N : int Order of base quadrature rule hk : double submesh element diameter x0 : integrand parameter y0 : integrand parameter """ quad = Quadrature.GaussTriangle(N) comp_quad = Quadrature.CompositeTriangle(quad, hk) N = int(np.ceil(old_div(1, hk))) ii = np.sum(comp_quad.weights[np.less_equal( comp_quad.points[:, 0] * y0 + comp_quad.points[:, 1] * x0, x0 * y0)]) ee = np.abs(ii - x0 * y0 * 0.5) logEvent("hk=%f\t true-int=%f\t comp-int=%f error=%f" % (old_div(1.0, N), x0 * y0 * 0.5, ii, ee)) return old_div(1.0, N), ee
def computeElementMaterials(self, rho_transfer, nu_transfer): #get quadrature points at element centroid and evaluate at shape functions from proteus import Quadrature transferQpt = Quadrature.SimplexGaussQuadrature(self.domain.nd, 1) qpt_centroid = numpy.asarray([transferQpt.points[0]]) materialSpace = self.nList[0].femSpaces[0]( self.modelList[0].levelModelList[0].mesh.subdomainMesh, self.domain.nd) materialSpace.getBasisValuesRef(qpt_centroid) from proteus.ctransportCoefficients import smoothedHeaviside IEN = self.modelList[ self.phaseIdx].levelModelList[0].u[0].femSpace.dofMap.l2g for (eID, dofs) in enumerate(IEN): phi_val = 0.0 for idx in range(len(dofs)): phi_val += materialSpace.psi[0][idx] * self.modelList[ self.phaseIdx].levelModelList[0].u[0].dof[dofs[idx]] #heaviside h_phi = 0.0 for idx in range(len(dofs)): h_phi += (materialSpace.psi[0][idx]) * ( self.modelList[self.phaseIdx].levelModelList[0].mesh. nodeDiametersArray[dofs[idx]]) eps_rho = self.epsFact_density * h_phi smoothed_phi_val = smoothedHeaviside(eps_rho, phi_val) rho_transfer[eID] = (1.0 - smoothed_phi_val ) * self.rho_0 + smoothed_phi_val * self.rho_1 nu_transfer[eID] = (1.0 - smoothed_phi_val ) * self.nu_0 + smoothed_phi_val * self.nu_1
def gauge_setup(nd, total_nodes=None): comm = Comm.get() #Simplified Physics p.name = "test_gauges" p.nd = nd class LinearSolution(object): def uOfXT(self, x, t): return (x[0] + 10 * x[1] + 100 * x[2]) * (t + 1.0) p.initialConditions = {0: LinearSolution()} p.dirichletConditions = {0: lambda x, flag: None} p.domain = Domain.RectangularDomain(name="test_gauges_domain") p.coefficients = TransportCoefficients.PoissonEquationCoefficients( aOfX=[lambda x: np.eye(p.nd, p.nd)], fOfX=[lambda x: 0], nc=1, nd=p.nd) #Simplified and Incomplete Numerics n.femSpaces = {0: FemTools.C0_AffineLinearOnSimplexWithNodalBasis} n.elementQuadrature = Quadrature.SimplexGaussQuadrature(p.nd, 3) n.elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature( p.nd - 1, 3) n.numericalFluxType = NumericalFlux.NoFlux n.cfluxtag = None n.conservativeFlux = None if total_nodes is None: total_nodes = 2 * comm.size() if p.nd == 1: mlMesh = build1DMesh(p, total_nodes + 1) elif p.nd == 2: nnx = nny = int(ceil(sqrt(total_nodes))) + 1 mlMesh = build2DMesh(p, nnx, nny) elif p.nd == 3: nnx = nny = nnz = int(ceil(pow(total_nodes, old_div(1.0, 3.0)))) + 1 mlMesh = build3DMesh(p, nnx, nny, nnz) model = Transport.MultilevelTransport(p, n, mlMesh) return model, p.initialConditions
def ex3(N, hk, r0): r""" Compute the integral of :math:`1_{|[x,y,z]|<= r0}` :math: `r0<=0.5*sqrt(2)` Parameters ---------- N : int Order of base quadrature rule hk : double submesh element diameter r0 : integrand parameter """ quad = Quadrature.GaussTetrahedron(N) comp_quad = Quadrature.CompositeTetrahedron(quad, hk) ii = np.sum(comp_quad.weights[np.less_equal( comp_quad.points[:, 0] ** 2 + comp_quad.points[:, 1] ** 2 + comp_quad.points[:, 2] ** 2, r0 * r0)]) ee = np.abs(ii - r0**3 * np.pi / 6.0) logEvent("hk=%f\t true-int=%f\t comp-int=%f error=%f" % (comp_quad.h, r0**3 * np.pi / 6.0, ii, ee)) return comp_quad.h, ee
def test_poiseuilleError(verbose=0): """Test for loading gmsh mesh through PUMI, estimating error for a Poiseuille flow case. The estimated error should be larger than the exact error in the seminorm""" testDir = os.path.dirname(os.path.abspath(__file__)) Model = testDir + '/Couette.null' Mesh = testDir + '/Couette.msh' domain = Domain.PUMIDomain() #initialize the domain domain.PUMIMesh = MeshAdaptPUMI.MeshAdaptPUMI(hmax=0.01, hmin=0.008, numIter=1, sfConfig='ERM', maType='isotropic', logType='off') domain.PUMIMesh.loadModelAndMesh(Model, Mesh) domain.faceList = [[80], [76], [42], [24], [82], [78]] mesh = MeshTools.TetrahedralMesh() mesh.cmesh = cmeshTools.CMesh() comm = Comm.init() nElements_initial = mesh.nElements_global mesh.convertFromPUMI(domain.PUMIMesh, domain.faceList, domain.regList, parallel=comm.size() > 1, dim=domain.nd) domain.PUMIMesh.transferFieldToPUMI("coordinates", mesh.nodeArray) rho = numpy.array([998.2, 998.2]) nu = numpy.array([1.004e-6, 1.004e-6]) g = numpy.asarray([0.0, 0.0, 0.0]) deltaT = 1.0 #dummy number domain.PUMIMesh.transferPropertiesToPUMI(rho, nu, g, deltaT) #Poiseuille Flow Ly = 0.2 Lz = 0.05 Re = 100 Umax = Re * nu[0] / Lz def vOfX(x): return 4 * Umax / (Lz**2) * (x[2]) * (Lz - x[2]) def dvOfXdz(x): return 4 * Umax / (Lz**2) * (Lz - 2 * x[2]) #hard code solution vector = numpy.zeros((mesh.nNodes_global, 3), 'd') dummy = numpy.zeros(mesh.nNodes_global) vector[:, 0] = dummy vector[:, 1] = 4 * Umax / (Lz**2) * (mesh.nodeArray[:, 2]) * ( Lz - mesh.nodeArray[:, 2]) #v-velocity vector[:, 2] = dummy domain.PUMIMesh.transferFieldToPUMI("velocity", vector) scalar = numpy.zeros((mesh.nNodes_global, 1), 'd') domain.PUMIMesh.transferFieldToPUMI("p", scalar) scalar[:, 0] = mesh.nodeArray[:, 2] domain.PUMIMesh.transferFieldToPUMI("phi", scalar) del scalar scalar = numpy.zeros((mesh.nNodes_global, 1), 'd') + 1.0 domain.PUMIMesh.transferFieldToPUMI("vof", scalar) errorTotal = domain.PUMIMesh.get_local_error() # load the femspace with linear basis and get the quadrature points on a reference element elementQuadrature = Quadrature.SimplexGaussQuadrature(domain.nd, 3) ok(mesh.nNodes_element == 4) #confirm all of the elements have 4 nodes #hard code computation for H1 seminorm; ideally will be reformatted using the classes within proteus derivativeArrayRef = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [-1, -1, -1]] error = 0 for eID in range(mesh.nElements_global): nodes = mesh.elementNodesArray[eID] coords = [] for i in range(mesh.nNodes_element): coords.append(mesh.nodeArray[nodes[i]]) J = numpy.matrix([[ coords[0][0] - coords[3][0], coords[1][0] - coords[3][0], coords[2][0] - coords[3][0] ], [ coords[0][1] - coords[3][1], coords[1][1] - coords[3][1], coords[2][1] - coords[3][1] ], [ coords[0][2] - coords[3][2], coords[1][2] - coords[3][2], coords[2][2] - coords[3][2] ]]) invJ = J.I detJ = numpy.linalg.det(J) gradPhi_h = 0 for k in range(len(elementQuadrature.points)): tempQpt = 0 zCoord = elementQuadrature.points[k][0]*coords[0][2] \ +elementQuadrature.points[k][1]*coords[1][2] \ +elementQuadrature.points[k][2]*coords[2][2] \ +(1-elementQuadrature.points[k][0]-elementQuadrature.points[k][1]-elementQuadrature.points[k][2])*coords[3][2] for i in range(mesh.nNodes_element): temp = 0 for j in range(domain.nd): temp = temp + derivativeArrayRef[i][j] * invJ[j, 2] tempQpt = tempQpt + vector[nodes[i]][1] * temp exactgradPhi = dvOfXdz([0, 0, zCoord]) gradPhi_h = gradPhi_h + tempQpt error = error + (exactgradPhi - gradPhi_h )**2 * elementQuadrature.weights[k] * abs(detJ) error = sqrt(error) ok(error < errorTotal)
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 __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=True): self.bdyNullSpace = bdyNullSpace 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.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) # # simplified allocations for test==trial and also check if space is mixed or not # self.added_mass_i = 0; self.Aij = np.zeros((self.coefficients.flags_rigidbody.shape[0], 6, 6), 'd') 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.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.q[('v', 0)] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nDOF_trial_element[0]), 'd') self.q['J'] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global, self.nSpace_global), 'd') self.q['det(J)'] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q['inverse(J)'] = numpy.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global, self.nSpace_global), 'd') self.ebq[('v', 0)] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nDOF_trial_element[0]), 'd') self.ebq[('w', 0)] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nDOF_trial_element[0]), 'd') self.ebq['x'] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.ebq['hat(x)'] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.ebq['inverse(J)'] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global, self.nSpace_global), 'd') self.ebq['g'] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global - 1, self.nSpace_global - 1), 'd') self.ebq['sqrt(det(g))'] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebq['n'] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebq[('dS_u', 0)] = numpy.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe['dS'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('dS_u', 0)] = self.ebqe['dS'] self.ebqe['n'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebqe['inverse(J)'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global, self.nSpace_global), 'd') self.ebqe['g'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global - 1, self.nSpace_global - 1), 'd') self.ebqe['sqrt(det(g))'] = numpy.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebq_global['n'] = numpy.zeros( (self.mesh.nElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebq_global['x'] = numpy.zeros( (self.mesh.nElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), '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[('diffusiveFlux', 0, 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() logEvent(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 logEvent("Updating local to global mappings", 2) self.updateLocal2Global() logEvent("Building time integration object", 2) logEvent(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) logEvent(memory("TimeIntegration", "OneLevelTransport"), level=4) logEvent("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" logEvent(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 # strong Dirichlet self.dirichletConditionsForceDOF = {0: DOFBoundaryConditions(self.u[cj].femSpace, dofBoundaryConditionsSetterDict[cj], weakDirichletConditions=False)} # 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 logEvent(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) logEvent(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 self.addedMass = cAddedMass.AddedMass( 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) self.barycenters = self.coefficients.barycenters self.flags_rigidbody = self.coefficients.flags_rigidbody
def __init__(self, uDict, phiDict, testSpaceDict, matType, dofBoundaryConditionsDict, dofBoundaryConditionsSetterDict, coefficients, elementQuadrature, elementBoundaryQuadrature, fluxBoundaryConditionsDict=None, advectiveFluxBoundaryConditionsSetterDict=None, diffusiveFluxBoundaryConditionsSetterDictDict=None, stressFluxBoundaryConditionsSetterDict=None, stabilization=None, shockCapturing=None, conservativeFluxDict=None, numericalFluxType=None, TimeIntegrationClass=None, massLumping=False, reactionLumping=False, options=None, name='Plasticity', reuse_trial_and_test_quadrature=True, sd=True, movingDomain=False, bdyNullSpace=False): # # set the objects describing the method and boundary conditions # self.bdyNullSpace = bdyNullSpace self.moveCalls = 0 self.movingDomain = movingDomain self.tLast_mesh = None self.bdyNullSpace = bdyNullSpace # # cek todo clean up these flags in the optimized version self.bcsTimeDependent = options.bcsTimeDependent self.bcsSet = False self.name = name self.sd = sd self.lowmem = True self.timeTerm = True # allow turning off the time derivative self.testIsTrial = True self.phiTrialIsTrial = True self.u = uDict self.Hess = False if isinstance(self.u[0].femSpace, FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis): self.Hess = True 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.stressFluxBoundaryConditionsSetterDict = stressFluxBoundaryConditionsSetterDict # 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 ci in coefficients.mass: for flag in list(coefficients.mass[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.advection: for flag in list(coefficients.advection[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.diffusion: for diffusionDict in list( coefficients.diffusion[ci].values()): for flag in list(diffusionDict.values()): if flag != 'constant': self.stabilizationIsNonlinear = True if ci in coefficients.potential: for flag in list(coefficients.potential[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.reaction: for flag in list(coefficients.reaction[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.hamiltonian: for flag in list(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 list(self.u.values()) ] self.nDOF_phi_trial_element = [ phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values()) ] self.n_phi_ip_element = [ phi_k.femSpace.referenceFiniteElement.interpolationConditions. nQuadraturePoints for phi_k in list(self.phi.values()) ] self.nDOF_test_element = [ femSpace.max_nDOF_element for femSpace in list(self.testSpace.values()) ] self.nFreeDOF_global = [ dc.nFreeDOF_global for dc in list(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 I in elementQuadrature: 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 I in elementQuadrature: 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 ('numDiff', ci, ci) in elementQuadrature: 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 list(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 list(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 I in elementBoundaryQuadrature: 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) # # 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.ebqe['x'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.q['bodyForce'] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global), 'd') self.ebqe[('u', 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('u', 1)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('u', 2)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('stressFlux_bc_flag', 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'i') self.ebqe[('stressFlux_bc_flag', 1)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'i') self.ebqe[('stressFlux_bc_flag', 2)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'i') self.ebqe[('stressFlux_bc', 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('stressFlux_bc', 1)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('stressFlux_bc', 2)] = np.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() # # show quadrature # logEvent("Dumping quadrature shapes for model %s" % self.name, level=9) logEvent("Element quadrature array (q)", level=9) for (k, v) in list(self.q.items()): logEvent(str((k, v.shape)), level=9) logEvent("Element boundary quadrature (ebq)", level=9) for (k, v) in list(self.ebq.items()): logEvent(str((k, v.shape)), level=9) logEvent("Global element boundary quadrature (ebq_global)", level=9) for (k, v) in list(self.ebq_global.items()): logEvent(str((k, v.shape)), level=9) logEvent("Exterior element boundary quadrature (ebqe)", level=9) for (k, v) in list(self.ebqe.items()): logEvent(str((k, v.shape)), level=9) logEvent( "Interpolation points for nonlinear diffusion potential (phi_ip)", level=9) for (k, v) in list(self.phi_ip.items()): logEvent(str((k, v.shape)), level=9) # # allocate residual and Jacobian storage # self.elementResidual = [ np.zeros((self.mesh.nElements_global, self.nDOF_test_element[ci]), 'd') for ci in range(self.nc) ] self.elementSpatialResidual = [ np.zeros((self.mesh.nElements_global, self.nDOF_test_element[ci]), 'd') for ci in range(self.nc) ] self.inflowBoundaryBC = {} self.inflowBoundaryBC_values = {} self.inflowFlux = {} for cj in range(self.nc): self.inflowBoundaryBC[cj] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, ), 'i') self.inflowBoundaryBC_values[cj] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nDOF_trial_element[cj]), 'd') self.inflowFlux[cj] = np.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 = np.zeros((self.nNodes_internal, ), 'i') for nI, n in enumerate(self.internalNodes): self.internalNodesArray[nI] = n # del self.internalNodes self.internalNodes = None logEvent("Updating local to global mappings", 2) self.updateLocal2Global() logEvent("Building time integration object", 2) logEvent(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) logEvent(memory("TimeIntegration", "OneLevelTransport"), level=4) logEvent("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" logEvent(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 'penalty' in self.ebq_global: for ebN in range(self.mesh.nElementBoundaries_global): for k in range( self.nElementBoundaryQuadraturePoints_elementBoundary): self.ebq_global['penalty'][ebN, k] = old_div(self.numericalFlux.penalty_constant, \ (self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) # penalty term # cek move to Numerical flux initialization if 'penalty' in self.ebqe: 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] = old_div(self.numericalFlux.penalty_constant, \ self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) logEvent(memory("numericalFlux", "OneLevelTransport"), level=4) self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray # use post processing tools to get conservative fluxes, None by default # helper for writing out data storage import proteus.Archiver self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter( ) for ci, sbcObject in list( self.stressFluxBoundaryConditionsObjectsDict.items()): self.ebqe[('stressFlux_bc_flag', ci)] = np.zeros(self.ebqe[('stressFlux_bc', ci)].shape, 'i') for t, g in list( sbcObject.stressFluxBoundaryConditionsDict.items()): self.ebqe[('stressFlux_bc', ci)][t[0], t[1]] = g(self.ebqe[('x')][t[0], t[1]], self.timeIntegration.t) self.ebqe[('stressFlux_bc_flag', ci)][t[0], t[1]] = 1 self.numericalFlux.setDirichletValues(self.ebqe) if self.mesh.nodeVelocityArray is None: self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape, 'd') compKernelFlag = 0 if self.nSpace_global == 2: import copy self.u[2] = self.u[1].copy() self.u[2].name = 'hz' self.offset.append(self.offset[1]) self.stride.append(self.stride[1]) self.numericalFlux.isDOFBoundary[ 2] = self.numericalFlux.isDOFBoundary[1].copy() self.numericalFlux.ebqe[('u', 2)] = self.numericalFlux.ebqe[('u', 1)].copy() logEvent("calling cMoveMesh2D_base ctor") self.moveMesh = cMoveMesh2D_base( 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) else: logEvent("calling cMoveMesh_base ctor") self.moveMesh = cMoveMesh_base( 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) self.disp0 = np.zeros(self.nSpace_global, 'd') self.disp1 = np.zeros(self.nSpace_global, 'd') self.vel0 = np.zeros(self.nSpace_global, 'd') self.vel1 = np.zeros(self.nSpace_global, 'd') self.rot0 = np.eye(self.nSpace_global, dtype=float) self.rot1 = np.eye(self.nSpace_global, dtype=float) self.angVel0 = np.zeros(self.nSpace_global, 'd') self.angVel1 = np.zeros(self.nSpace_global, 'd') self.forceStrongConditions = True # False#True self.dirichletConditionsForceDOF = {} if self.forceStrongConditions: for cj in range(self.nc): self.dirichletConditionsForceDOF[ cj] = FemTools.DOFBoundaryConditions( self.u[cj].femSpace, dofBoundaryConditionsSetterDict[cj], weakDirichletConditions=False) from proteus import PostProcessingTools self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser( self) logEvent(memory("velocity postprocessor", "OneLevelTransport"), level=4)
n.stepController = StepControl.Min_dt_cfl_controller n.systemStepExact = True if opts.spaceOrder == 1: if opts.triangles: if opts.useTaylorHood: n.femSpaces = { 0: FemTools.C0_AffineLinearOnSimplexWithNodalBasis, 1: FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis, 2: FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis } if p.nd == 3: n.femSpaces[ 3] = FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis n.elementQuadrature = Quadrature.SimplexGaussQuadrature(p.nd, 5) n.elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature( p.nd - 1, 5) else: n.femSpaces = { 0: FemTools.C0_AffineLinearOnSimplexWithNodalBasis, 1: FemTools.C0_AffineLinearOnSimplexWithNodalBasis, 2: FemTools.C0_AffineLinearOnSimplexWithNodalBasis } if p.nd == 3: n.femSpaces[ 3] = FemTools.C0_AffineLinearOnSimplexWithNodalBasis n.elementQuadrature = Quadrature.SimplexGaussQuadrature(p.nd, 5) n.elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature( p.nd - 1, 5) else:
if useRBLES not in [0.0, 1.0]: print "INVALID: useRBLES" + useRBLES sys.exit() if useMetrics not in [0.0, 1.0]: print "INVALID: useMetrics" sys.exit() # Discretization nd = 2 if spaceOrder == 1: hFactor=1.0 if useHex: basis=FemTools.C0_AffineLinearOnCubeWithNodalBasis elementQuadrature = Quadrature.CubeGaussQuadrature(nd,3) elementBoundaryQuadrature = Quadrature.CubeGaussQuadrature(nd-1,3) else: basis=FemTools.C0_AffineLinearOnSimplexWithNodalBasis elementQuadrature = Quadrature.SimplexGaussQuadrature(nd,3) elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature(nd-1,3) elif spaceOrder == 2: hFactor=0.5 if useHex: basis=FemTools.C0_AffineLagrangeOnCubeWithNodalBasis elementQuadrature = Quadrature.CubeGaussQuadrature(nd,4) elementBoundaryQuadrature = Quadrature.CubeGaussQuadrature(nd-1,4) else: basis=FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis elementQuadrature = Quadrature.SimplexGaussQuadrature(nd,4)
def PUMI_transferFields(self): p0 = self.pList[0].ct n0 = self.nList[0].ct if self.TwoPhaseFlow: domain = p0.myTpFlowProblem.domain rho_0 = p0.myTpFlowProblem.physical_parameters['densityA'] nu_0 = p0.myTpFlowProblem.physical_parameters[ 'kinematicViscosityA'] rho_1 = p0.myTpFlowProblem.physical_parameters['densityB'] nu_1 = p0.myTpFlowProblem.physical_parameters[ 'kinematicViscosityB'] g = p0.myTpFlowProblem.physical_parameters['gravity'] epsFact_density = p0.myTpFlowProblem.clsvof_parameters[ 'epsFactHeaviside'] else: domain = p0.domain rho_0 = p0.rho_0 nu_0 = p0.nu_0 rho_1 = p0.rho_1 nu_1 = p0.nu_1 g = p0.g epsFact_density = p0.epsFact_density logEvent("Copying coordinates to PUMI") domain.PUMIMesh.transferFieldToPUMI( b"coordinates", self.modelList[0].levelModelList[0].mesh.nodeArray) #I want to compute the density and viscosity arrays here #arrays are length = number of elements and will correspond to density at center of element rho_transfer = numpy.zeros( (self.modelList[0].levelModelList[0].mesh.nElements_owned), 'd') nu_transfer = numpy.zeros( (self.modelList[0].levelModelList[0].mesh.nElements_owned), 'd') #get quadrature points at element centroid and evaluate at shape functions from proteus import Quadrature transferQpt = Quadrature.SimplexGaussQuadrature(p0.domain.nd, 1) qpt_centroid = numpy.asarray([transferQpt.points[0]]) materialSpace = self.nList[0].femSpaces[0]( self.modelList[0].levelModelList[0].mesh.subdomainMesh, p0.domain.nd) materialSpace.getBasisValuesRef(qpt_centroid) #obtain the level-set or vof value at each element centroid #pass through heaviside function to get material property from proteus.ctransportCoefficients import smoothedHeaviside IEN = self.modelList[2].levelModelList[0].u[0].femSpace.dofMap.l2g for (eID, dofs) in enumerate(IEN): phi_val = 0.0 for idx in range(len(dofs)): phi_val += materialSpace.psi[0][idx] * self.modelList[ 2].levelModelList[0].u[0].dof[dofs[idx]] #rho_transfer[eID] = phi_val #heaviside h_phi = 0.0 for idx in range(len(dofs)): h_phi += (materialSpace.psi[0][idx]) * (self.modelList[ 2].levelModelList[0].mesh.nodeDiametersArray[dofs[idx]]) eps_rho = p0.epsFact_density * h_phi smoothed_phi_val = smoothedHeaviside(eps_rho, phi_val) rho_transfer[eID] = (1.0 - smoothed_phi_val) * self.pList[ 0].ct.rho_0 + smoothed_phi_val * self.pList[0].ct.rho_1 nu_transfer[eID] = (1.0 - smoothed_phi_val) * self.pList[ 0].ct.nu_0 + smoothed_phi_val * self.pList[0].ct.nu_1 self.modelList[0].levelModelList[0].mesh.elementMaterial = numpy.zeros( (self.modelList[0].levelModelList[0].mesh.nElements_owned), 'd') self.modelList[0].levelModelList[ 0].mesh.elementMaterial[:] = rho_transfer[:] #put the solution field as uList #VOF and LS needs to reset the u.dof array for proper transfer #but needs to be returned to the original form if not actually adapting....be careful with the following statements, unsure if this doesn't break something else import copy for m in self.modelList: for lm in m.levelModelList: lm.u_store = lm.u.copy() for ci in range(0, lm.coefficients.nc): lm.u_store[ci] = lm.u[ci].copy() self.modelList[1].levelModelList[0].setUnknowns( self.modelList[1].uList[0]) self.modelList[2].levelModelList[0].setUnknowns( self.modelList[2].uList[0]) logEvent("Copying DOF and parameters to PUMI") for m in self.modelList: for lm in m.levelModelList: coef = lm.coefficients if coef.vectorComponents is not None: vector = numpy.zeros((lm.mesh.nNodes_global, 3), 'd') for vci in range(len(coef.vectorComponents)): vector[:, vci] = lm.u[coef.vectorComponents[vci]].dof[:] domain.PUMIMesh.transferFieldToPUMI( coef.vectorName.encode('utf-8'), vector) #Transfer dof_last for vci in range(len(coef.vectorComponents)): vector[:, vci] = lm.u[ coef.vectorComponents[vci]].dof_last[:] domain.PUMIMesh.transferFieldToPUMI( coef.vectorName.encode('utf-8') + b"_old", vector) #Transfer dof_last_last for vci in range(len(coef.vectorComponents)): vector[:, vci] = lm.u[ coef.vectorComponents[vci]].dof_last_last[:] p0.domain.PUMIMesh.transferFieldToPUMI( coef.vectorName.encode('utf-8') + b"_old_old", vector) del vector for ci in range(coef.nc): if coef.vectorComponents is None or \ ci not in coef.vectorComponents: scalar = numpy.zeros((lm.mesh.nNodes_global, 1), 'd') scalar[:, 0] = lm.u[ci].dof[:] domain.PUMIMesh.transferFieldToPUMI( coef.variableNames[ci].encode('utf-8'), scalar) #Transfer dof_last scalar[:, 0] = lm.u[ci].dof_last[:] domain.PUMIMesh.transferFieldToPUMI( coef.variableNames[ci].encode('utf-8') + b"_old", scalar) #Transfer dof_last_last scalar[:, 0] = lm.u[ci].dof_last_last[:] p0.domain.PUMIMesh.transferFieldToPUMI( coef.variableNames[ci].encode('utf-8') + b"_old_old", scalar) del scalar scalar = numpy.zeros((lm.mesh.nNodes_global, 1), 'd') del scalar #Get Physical Parameters #Can we do this in a problem-independent way? rho = numpy.array([rho_0, rho_1]) nu = numpy.array([nu_0, nu_1]) g = numpy.asarray(g) #This condition is to account for adapting before the simulation started if (hasattr(self, "tn")): #deltaT = self.tn-self.tn_last #is actually the time step for next step, self.tn and self.tn_last refer to entries in tnList #deltaT = self.systemStepController.dt_system deltaT = self.modelList[0].levelModelList[0].timeIntegration.dtLast T_current = self.systemStepController.t_system_last deltaT_next = self.systemStepController.dt_system else: deltaT = 0 deltaT_next = 0.0 T_current = 0.0 epsFact = epsFact_density #domain.PUMIMesh.transferPropertiesToPUMI(rho,nu,g,deltaT,epsFact) domain.PUMIMesh.transferPropertiesToPUMI(rho_transfer, nu_transfer, g, deltaT, deltaT_next, T_current, epsFact) del rho, nu, g, epsFact
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 # 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.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 ci in coefficients.mass: for flag in list(coefficients.mass[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.advection: for flag in list(coefficients.advection[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.diffusion: for diffusionDict in list(coefficients.diffusion[ci].values()): for flag in list(diffusionDict.values()): if flag != 'constant': self.stabilizationIsNonlinear = True if ci in coefficients.potential: for flag in list(coefficients.potential[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.reaction: for flag in list(coefficients.reaction[ci].values()): if flag == 'nonlinear': self.stabilizationIsNonlinear = True if ci in coefficients.hamiltonian: for flag in list(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 list(self.u.values())] self.nDOF_phi_trial_element = [ phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] self.n_phi_ip_element = [ phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] self.nDOF_test_element = [ femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] self.nFreeDOF_global = [ dc.nFreeDOF_global for dc in list(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 I in elementQuadrature: 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 I in elementQuadrature: 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 ('numDiff', ci, ci) in elementQuadrature: 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 list(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 list(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 I in elementBoundaryQuadrature: 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) # # simplified allocations for test==trial and also check if space is mixed or not # self.added_mass_i = 0; self.Aij = np.zeros((self.coefficients.flags_rigidbody.shape[0], 6, 6), 'd') self.q = {} self.ebq = {} self.ebq_global = {} self.ebqe = {} self.phi_ip = {} # mesh #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') self.ebqe['x'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.q[('u', 0)] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q[ ('grad(u)', 0)] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global), 'd') self.ebqe[ ('u', 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[ ('grad(u)', 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.q[('v', 0)] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nDOF_trial_element[0]), 'd') self.q['J'] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global, self.nSpace_global), 'd') self.q['det(J)'] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') self.q['inverse(J)'] = np.zeros( (self.mesh.nElements_global, self.nQuadraturePoints_element, self.nSpace_global, self.nSpace_global), 'd') self.ebq[('v', 0)] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nDOF_trial_element[0]), 'd') self.ebq[('w', 0)] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nDOF_trial_element[0]), 'd') self.ebq['x'] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.ebq['hat(x)'] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.ebq['inverse(J)'] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global, self.nSpace_global), 'd') self.ebq['g'] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global - 1, self.nSpace_global - 1), 'd') self.ebq['sqrt(det(g))'] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebq['n'] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebq[('dS_u', 0)] = np.zeros( (self.mesh.nElements_global, self.mesh.nElementBoundaries_element, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe['dS'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('dS_u', 0)] = self.ebqe['dS'] self.ebqe['n'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebqe['inverse(J)'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global, self.nSpace_global), 'd') self.ebqe['g'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global - 1, self.nSpace_global - 1), 'd') self.ebqe['sqrt(det(g))'] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebq_global['n'] = np.zeros( (self.mesh.nElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, self.nSpace_global), 'd') self.ebq_global['x'] = np.zeros( (self.mesh.nElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary, 3), 'd') self.ebqe[('diffusiveFlux_bc_flag', 0, 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'i') self.ebqe[('diffusiveFlux_bc', 0, 0)] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nElementBoundaryQuadraturePoints_elementBoundary), 'd') self.ebqe[('diffusiveFlux', 0, 0)] = np.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() logEvent(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] = np.zeros( (self.mesh.nExteriorElementBoundaries_global,), 'i') self.inflowBoundaryBC_values[cj] = np.zeros( (self.mesh.nExteriorElementBoundaries_global, self.nDOF_trial_element[cj]), 'd') self.inflowFlux[cj] = np.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 = np.zeros((self.nNodes_internal,), 'i') for nI, n in enumerate(self.internalNodes): self.internalNodesArray[nI] = n # del self.internalNodes self.internalNodes = None logEvent("Updating local to global mappings", 2) self.updateLocal2Global() logEvent("Building time integration object", 2) logEvent(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) logEvent(memory("TimeIntegration", "OneLevelTransport"), level=4) logEvent("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" logEvent(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 # strong Dirichlet self.dirichletConditionsForceDOF = {0: DOFBoundaryConditions(self.u[cj].femSpace, dofBoundaryConditionsSetterDict[cj], weakDirichletConditions=False)} # set penalty terms # cek todo move into numerical flux initialization if 'penalty' in self.ebq_global: for ebN in range(self.mesh.nElementBoundaries_global): for k in range( self.nElementBoundaryQuadraturePoints_elementBoundary): self.ebq_global['penalty'][ebN, k] = old_div(self.numericalFlux.penalty_constant, ( self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) # penalty term # cek move to Numerical flux initialization if 'penalty' in self.ebqe: 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] = old_div(self.numericalFlux.penalty_constant, \ self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) logEvent(memory("numericalFlux", "OneLevelTransport"), level=4) self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray # 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 self.addedMass = cAddedMass.newAddedMass( 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) self.barycenters = self.coefficients.barycenters self.flags_rigidbody = self.coefficients.flags_rigidbody