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, 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)