def attachModel(self,model,ar): self.model=model self.ar=ar self.writer = Archiver.XdmfWriter() self.nd = model.levelModelList[-1].nSpace_global m = self.model.levelModelList[-1] flagMax = max(m.mesh.elementBoundaryMaterialTypes) flagMin = min(m.mesh.elementBoundaryMaterialTypes) assert(flagMin >= 0) assert(flagMax <= 7) self.nForces=flagMax+1 assert(self.nForces <= 8) return self
def refine_uniform_from_tetgen(filebase,refinementLevels,index_base=0,EB=False): from proteus import MeshTools,Archiver mesh = MeshTools.TetrahedralMesh() mesh.generateFromTetgenFiles(filebase,index_base,skipGeometricInit=False) MLMesh = MeshTools.MultilevelTetrahedralMesh(0,0,0,skipInit=True) MLMesh.generateFromExistingCoarseMesh(mesh,refinementLevels) MLMesh.meshList[-1].writeTetgenFiles(filebase+'_out',index_base) ar = Archiver.XdmfArchive('.',filebase+'_out') import xml.etree.ElementTree as ElementTree ar.domain = ElementTree.SubElement(ar.tree.getroot(),"Domain") mesh.writeMeshXdmf(ar,'mesh_coarse'+'_out',init=True,EB=EB,tCount=0) MLMesh.meshList[-1].writeMeshXdmf(ar,'mesh_fine'+'_out',init=True,EB=EB,tCount=1) ar.close()
def test_svd_soln(): """ test SVD decomposition of solution by generating SVD, saving to file and reloading """ from proteus.deim_utils import read_snapshots, generate_svd_decomposition ns = get_burgers_ns("test_svd_soln", T=0.1, nDTout=10, archive_pod_res=True) failed = ns.calculateSolution("run_svd_soln") assert not failed from proteus import Archiver archive = Archiver.XdmfArchive(".", "test_svd_soln", readOnly=True) U, s, V = generate_svd_decomposition(archive, len(ns.tnList), 'u', 'soln') S_svd = np.dot(U, np.dot(np.diag(s), V)) #now load back in and test S = read_snapshots(archive, len(ns.tnList), 'u') npt.assert_almost_equal(S, S_svd)
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)
#!/usr/bin/env python from burgers_init import use_deim from proteus import deim_utils,Archiver from proteus.deim_utils import read_snapshots T = 1.0 nDTout = 100 DT = T/float(nDTout) archive = Archiver.XdmfArchive(".",burgers_init.physics.name,readOnly=True) import numpy as np #generate snapshots for solution S = read_snapshots(archive,nDTout+1,'u',) U, s, V = np.linalg.svd(S, full_matrices=False) print 'SVD for solution done!' np.savetxt('SVD_basis', U, delimiter=' ') np.savetxt('Singular_values', s, delimiter=' ') if use_deim: Sf = read_snapshots(archive,nDTout+1,'spatial_residual0') Uf,sf,Vf = np.linalg.svd(Sf,full_matrices=False) print 'SVD for spatial residual done!' np.savetxt('Fs_SVD_basis', Uf, delimiter=' ') np.savetxt('Fs_Singular_values', sf, delimiter=' ') Sm = read_snapshots(archive,nDTout+1,'mass_residual0') Um,sm,Vm = np.linalg.svd(Sm,full_matrices=False) print 'SVD for mass residual done!' np.savetxt('Fm_SVD_basis', Um, delimiter=' ')
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
def deim_approx(T=0.1, nDTout=10, m=5, m_mass=5): """ Follow basic setup for DEIM approximation - generate a burgers solution, saving spatial and 'mass' residuals - generate SVDs for snapshots - for both residuals F_s and F_m - pick $m$, dimension for snapshot reduced basis $\mathbf{U}_m$ - call DEIM algorithm to determine $\vec \rho$ and compute projection matrix $\mathbf{P}_F=\mathbf{U}_m(\mathbf{P}^T\mathbf{U}_m)^{-1}$ For selected timesteps - extract fine grid solution from archive, $\vec y$ - for both residuals F=F_s and F_m - evaluate $\vec F(\vec y)$ at indices in $\vec \rho \rightarrow \vec c$ - apply DEIM interpolant $\tilde{\vec F} = \mathbf{P}_F\vec c$ - compute error $\|F-\tilde{\vec F}\| - visualize """ from proteus.deim_utils import read_snapshots, generate_svd_decomposition ##run fine grid problem ns = get_burgers_ns("test_deim_approx", T=T, nDTout=nDTout, archive_pod_res=True) failed = ns.calculateSolution("run_deim_approx") assert not failed from proteus import Archiver archive = Archiver.XdmfArchive(".", "test_deim_approx", readOnly=True) ##perform SVD on spatial residual U, s, V = generate_svd_decomposition(archive, len(ns.tnList), 'spatial_residual0', 'F_s') U_m, s_m, V_m = generate_svd_decomposition(archive, len(ns.tnList), 'mass_residual0', 'F_m') from proteus.deim_utils import deim_alg ##calculate DEIM indices and projection matrix rho, PF = deim_alg(U, m) #also 'mass' term rho_m, PF_m = deim_alg(U_m, m_mass) ##for comparison, grab snapshots of solution and residual Su = read_snapshots(archive, len(ns.tnList), 'u') Sf = read_snapshots(archive, len(ns.tnList), 'spatial_residual0') Sm = read_snapshots(archive, len(ns.tnList), 'mass_residual0') steps_to_test = np.arange(len(ns.tnList)) errors = np.zeros(len(steps_to_test), 'd') errors_mass = errors.copy() F_deim = np.zeros((Sf.shape[0], len(steps_to_test)), 'd') Fm_deim = np.zeros((Sf.shape[0], len(steps_to_test)), 'd') for i, istep in enumerate(steps_to_test): #solution on the fine grid u = Su[:, istep] #spatial residual evaluated from fine grid F = Sf[:, istep] #deim approximation on the fine grid F_deim[:, istep] = np.dot(PF, F[rho]) errors[i] = np.linalg.norm(F - F_deim[:, istep]) #repeat for 'mass residual' Fm = Sm[:, istep] #deim approximation on the fine grid Fm_deim[:, istep] = np.dot(PF_m, Fm[rho]) errors_mass[i] = np.linalg.norm(Fm - Fm_deim[:, istep]) # np.savetxt( "deim_approx_errors_space_test_T={0}_nDT={1}_m={2}.dat".format( T, nDTout, m), errors) np.savetxt( "deim_approx_errors_mass_test_T={0}_nDT={1}_m={2}.dat".format( T, nDTout, m_mass), errors_mass) return errors, errors_mass, F_deim, Fm_deim