def computeElementMaterials(self, rho_transfer, nu_transfer): #get quadrature points at element centroid and evaluate at shape functions from proteus import Quadrature transferQpt = Quadrature.SimplexGaussQuadrature(self.domain.nd, 1) qpt_centroid = numpy.asarray([transferQpt.points[0]]) materialSpace = self.nList[0].femSpaces[0]( self.modelList[0].levelModelList[0].mesh.subdomainMesh, self.domain.nd) materialSpace.getBasisValuesRef(qpt_centroid) from proteus.ctransportCoefficients import smoothedHeaviside IEN = self.modelList[ self.phaseIdx].levelModelList[0].u[0].femSpace.dofMap.l2g for (eID, dofs) in enumerate(IEN): phi_val = 0.0 for idx in range(len(dofs)): phi_val += materialSpace.psi[0][idx] * self.modelList[ self.phaseIdx].levelModelList[0].u[0].dof[dofs[idx]] #heaviside h_phi = 0.0 for idx in range(len(dofs)): h_phi += (materialSpace.psi[0][idx]) * ( self.modelList[self.phaseIdx].levelModelList[0].mesh. nodeDiametersArray[dofs[idx]]) eps_rho = self.epsFact_density * h_phi smoothed_phi_val = smoothedHeaviside(eps_rho, phi_val) rho_transfer[eID] = (1.0 - smoothed_phi_val ) * self.rho_0 + smoothed_phi_val * self.rho_1 nu_transfer[eID] = (1.0 - smoothed_phi_val ) * self.nu_0 + smoothed_phi_val * self.nu_1
def gauge_setup(nd, total_nodes=None): comm = Comm.get() #Simplified Physics p.name = "test_gauges" p.nd = nd class LinearSolution(object): def uOfXT(self, x, t): return (x[0] + 10 * x[1] + 100 * x[2]) * (t + 1.0) p.initialConditions = {0: LinearSolution()} p.dirichletConditions = {0: lambda x, flag: None} p.domain = Domain.RectangularDomain(name="test_gauges_domain") p.coefficients = TransportCoefficients.PoissonEquationCoefficients( aOfX=[lambda x: np.eye(p.nd, p.nd)], fOfX=[lambda x: 0], nc=1, nd=p.nd) #Simplified and Incomplete Numerics n.femSpaces = {0: FemTools.C0_AffineLinearOnSimplexWithNodalBasis} n.elementQuadrature = Quadrature.SimplexGaussQuadrature(p.nd, 3) n.elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature( p.nd - 1, 3) n.numericalFluxType = NumericalFlux.NoFlux n.cfluxtag = None n.conservativeFlux = None if total_nodes is None: total_nodes = 2 * comm.size() if p.nd == 1: mlMesh = build1DMesh(p, total_nodes + 1) elif p.nd == 2: nnx = nny = int(ceil(sqrt(total_nodes))) + 1 mlMesh = build2DMesh(p, nnx, nny) elif p.nd == 3: nnx = nny = nnz = int(ceil(pow(total_nodes, old_div(1.0, 3.0)))) + 1 mlMesh = build3DMesh(p, nnx, nny, nnz) model = Transport.MultilevelTransport(p, n, mlMesh) return model, p.initialConditions
def test_poiseuilleError(verbose=0): """Test for loading gmsh mesh through PUMI, estimating error for a Poiseuille flow case. The estimated error should be larger than the exact error in the seminorm""" testDir = os.path.dirname(os.path.abspath(__file__)) Model = testDir + '/Couette.null' Mesh = testDir + '/Couette.msh' domain = Domain.PUMIDomain() #initialize the domain domain.PUMIMesh = MeshAdaptPUMI.MeshAdaptPUMI(hmax=0.01, hmin=0.008, numIter=1, sfConfig='ERM', maType='isotropic', logType='off') domain.PUMIMesh.loadModelAndMesh(Model, Mesh) domain.faceList = [[80], [76], [42], [24], [82], [78]] mesh = MeshTools.TetrahedralMesh() mesh.cmesh = cmeshTools.CMesh() comm = Comm.init() nElements_initial = mesh.nElements_global mesh.convertFromPUMI(domain.PUMIMesh, domain.faceList, domain.regList, parallel=comm.size() > 1, dim=domain.nd) domain.PUMIMesh.transferFieldToPUMI("coordinates", mesh.nodeArray) rho = numpy.array([998.2, 998.2]) nu = numpy.array([1.004e-6, 1.004e-6]) g = numpy.asarray([0.0, 0.0, 0.0]) deltaT = 1.0 #dummy number domain.PUMIMesh.transferPropertiesToPUMI(rho, nu, g, deltaT) #Poiseuille Flow Ly = 0.2 Lz = 0.05 Re = 100 Umax = Re * nu[0] / Lz def vOfX(x): return 4 * Umax / (Lz**2) * (x[2]) * (Lz - x[2]) def dvOfXdz(x): return 4 * Umax / (Lz**2) * (Lz - 2 * x[2]) #hard code solution vector = numpy.zeros((mesh.nNodes_global, 3), 'd') dummy = numpy.zeros(mesh.nNodes_global) vector[:, 0] = dummy vector[:, 1] = 4 * Umax / (Lz**2) * (mesh.nodeArray[:, 2]) * ( Lz - mesh.nodeArray[:, 2]) #v-velocity vector[:, 2] = dummy domain.PUMIMesh.transferFieldToPUMI("velocity", vector) scalar = numpy.zeros((mesh.nNodes_global, 1), 'd') domain.PUMIMesh.transferFieldToPUMI("p", scalar) scalar[:, 0] = mesh.nodeArray[:, 2] domain.PUMIMesh.transferFieldToPUMI("phi", scalar) del scalar scalar = numpy.zeros((mesh.nNodes_global, 1), 'd') + 1.0 domain.PUMIMesh.transferFieldToPUMI("vof", scalar) errorTotal = domain.PUMIMesh.get_local_error() # load the femspace with linear basis and get the quadrature points on a reference element elementQuadrature = Quadrature.SimplexGaussQuadrature(domain.nd, 3) ok(mesh.nNodes_element == 4) #confirm all of the elements have 4 nodes #hard code computation for H1 seminorm; ideally will be reformatted using the classes within proteus derivativeArrayRef = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [-1, -1, -1]] error = 0 for eID in range(mesh.nElements_global): nodes = mesh.elementNodesArray[eID] coords = [] for i in range(mesh.nNodes_element): coords.append(mesh.nodeArray[nodes[i]]) J = numpy.matrix([[ coords[0][0] - coords[3][0], coords[1][0] - coords[3][0], coords[2][0] - coords[3][0] ], [ coords[0][1] - coords[3][1], coords[1][1] - coords[3][1], coords[2][1] - coords[3][1] ], [ coords[0][2] - coords[3][2], coords[1][2] - coords[3][2], coords[2][2] - coords[3][2] ]]) invJ = J.I detJ = numpy.linalg.det(J) gradPhi_h = 0 for k in range(len(elementQuadrature.points)): tempQpt = 0 zCoord = elementQuadrature.points[k][0]*coords[0][2] \ +elementQuadrature.points[k][1]*coords[1][2] \ +elementQuadrature.points[k][2]*coords[2][2] \ +(1-elementQuadrature.points[k][0]-elementQuadrature.points[k][1]-elementQuadrature.points[k][2])*coords[3][2] for i in range(mesh.nNodes_element): temp = 0 for j in range(domain.nd): temp = temp + derivativeArrayRef[i][j] * invJ[j, 2] tempQpt = tempQpt + vector[nodes[i]][1] * temp exactgradPhi = dvOfXdz([0, 0, zCoord]) gradPhi_h = gradPhi_h + tempQpt error = error + (exactgradPhi - gradPhi_h )**2 * elementQuadrature.weights[k] * abs(detJ) error = sqrt(error) ok(error < errorTotal)
n.stepController = StepControl.Min_dt_cfl_controller n.systemStepExact = True if opts.spaceOrder == 1: if opts.triangles: if opts.useTaylorHood: n.femSpaces = { 0: FemTools.C0_AffineLinearOnSimplexWithNodalBasis, 1: FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis, 2: FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis } if p.nd == 3: n.femSpaces[ 3] = FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis n.elementQuadrature = Quadrature.SimplexGaussQuadrature(p.nd, 5) n.elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature( p.nd - 1, 5) else: n.femSpaces = { 0: FemTools.C0_AffineLinearOnSimplexWithNodalBasis, 1: FemTools.C0_AffineLinearOnSimplexWithNodalBasis, 2: FemTools.C0_AffineLinearOnSimplexWithNodalBasis } if p.nd == 3: n.femSpaces[ 3] = FemTools.C0_AffineLinearOnSimplexWithNodalBasis n.elementQuadrature = Quadrature.SimplexGaussQuadrature(p.nd, 5) n.elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature( p.nd - 1, 5) else:
if useMetrics not in [0.0, 1.0]: print "INVALID: useMetrics" sys.exit() # Discretization nd = 2 if spaceOrder == 1: hFactor=1.0 if useHex: basis=FemTools.C0_AffineLinearOnCubeWithNodalBasis elementQuadrature = Quadrature.CubeGaussQuadrature(nd,3) elementBoundaryQuadrature = Quadrature.CubeGaussQuadrature(nd-1,3) else: basis=FemTools.C0_AffineLinearOnSimplexWithNodalBasis elementQuadrature = Quadrature.SimplexGaussQuadrature(nd,3) elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature(nd-1,3) elif spaceOrder == 2: hFactor=0.5 if useHex: basis=FemTools.C0_AffineLagrangeOnCubeWithNodalBasis elementQuadrature = Quadrature.CubeGaussQuadrature(nd,4) elementBoundaryQuadrature = Quadrature.CubeGaussQuadrature(nd-1,4) else: basis=FemTools.C0_AffineQuadraticOnSimplexWithNodalBasis elementQuadrature = Quadrature.SimplexGaussQuadrature(nd,4) elementBoundaryQuadrature = Quadrature.SimplexGaussQuadrature(nd-1,4) # Numerical parameters
def PUMI_transferFields(self): p0 = self.pList[0].ct n0 = self.nList[0].ct if self.TwoPhaseFlow: domain = p0.myTpFlowProblem.domain rho_0 = p0.myTpFlowProblem.physical_parameters['densityA'] nu_0 = p0.myTpFlowProblem.physical_parameters[ 'kinematicViscosityA'] rho_1 = p0.myTpFlowProblem.physical_parameters['densityB'] nu_1 = p0.myTpFlowProblem.physical_parameters[ 'kinematicViscosityB'] g = p0.myTpFlowProblem.physical_parameters['gravity'] epsFact_density = p0.myTpFlowProblem.clsvof_parameters[ 'epsFactHeaviside'] else: domain = p0.domain rho_0 = p0.rho_0 nu_0 = p0.nu_0 rho_1 = p0.rho_1 nu_1 = p0.nu_1 g = p0.g epsFact_density = p0.epsFact_density logEvent("Copying coordinates to PUMI") domain.PUMIMesh.transferFieldToPUMI( b"coordinates", self.modelList[0].levelModelList[0].mesh.nodeArray) #I want to compute the density and viscosity arrays here #arrays are length = number of elements and will correspond to density at center of element rho_transfer = numpy.zeros( (self.modelList[0].levelModelList[0].mesh.nElements_owned), 'd') nu_transfer = numpy.zeros( (self.modelList[0].levelModelList[0].mesh.nElements_owned), 'd') #get quadrature points at element centroid and evaluate at shape functions from proteus import Quadrature transferQpt = Quadrature.SimplexGaussQuadrature(p0.domain.nd, 1) qpt_centroid = numpy.asarray([transferQpt.points[0]]) materialSpace = self.nList[0].femSpaces[0]( self.modelList[0].levelModelList[0].mesh.subdomainMesh, p0.domain.nd) materialSpace.getBasisValuesRef(qpt_centroid) #obtain the level-set or vof value at each element centroid #pass through heaviside function to get material property from proteus.ctransportCoefficients import smoothedHeaviside IEN = self.modelList[2].levelModelList[0].u[0].femSpace.dofMap.l2g for (eID, dofs) in enumerate(IEN): phi_val = 0.0 for idx in range(len(dofs)): phi_val += materialSpace.psi[0][idx] * self.modelList[ 2].levelModelList[0].u[0].dof[dofs[idx]] #rho_transfer[eID] = phi_val #heaviside h_phi = 0.0 for idx in range(len(dofs)): h_phi += (materialSpace.psi[0][idx]) * (self.modelList[ 2].levelModelList[0].mesh.nodeDiametersArray[dofs[idx]]) eps_rho = p0.epsFact_density * h_phi smoothed_phi_val = smoothedHeaviside(eps_rho, phi_val) rho_transfer[eID] = (1.0 - smoothed_phi_val) * self.pList[ 0].ct.rho_0 + smoothed_phi_val * self.pList[0].ct.rho_1 nu_transfer[eID] = (1.0 - smoothed_phi_val) * self.pList[ 0].ct.nu_0 + smoothed_phi_val * self.pList[0].ct.nu_1 self.modelList[0].levelModelList[0].mesh.elementMaterial = numpy.zeros( (self.modelList[0].levelModelList[0].mesh.nElements_owned), 'd') self.modelList[0].levelModelList[ 0].mesh.elementMaterial[:] = rho_transfer[:] #put the solution field as uList #VOF and LS needs to reset the u.dof array for proper transfer #but needs to be returned to the original form if not actually adapting....be careful with the following statements, unsure if this doesn't break something else import copy for m in self.modelList: for lm in m.levelModelList: lm.u_store = lm.u.copy() for ci in range(0, lm.coefficients.nc): lm.u_store[ci] = lm.u[ci].copy() self.modelList[1].levelModelList[0].setUnknowns( self.modelList[1].uList[0]) self.modelList[2].levelModelList[0].setUnknowns( self.modelList[2].uList[0]) logEvent("Copying DOF and parameters to PUMI") for m in self.modelList: for lm in m.levelModelList: coef = lm.coefficients if coef.vectorComponents is not None: vector = numpy.zeros((lm.mesh.nNodes_global, 3), 'd') for vci in range(len(coef.vectorComponents)): vector[:, vci] = lm.u[coef.vectorComponents[vci]].dof[:] domain.PUMIMesh.transferFieldToPUMI( coef.vectorName.encode('utf-8'), vector) #Transfer dof_last for vci in range(len(coef.vectorComponents)): vector[:, vci] = lm.u[ coef.vectorComponents[vci]].dof_last[:] domain.PUMIMesh.transferFieldToPUMI( coef.vectorName.encode('utf-8') + b"_old", vector) #Transfer dof_last_last for vci in range(len(coef.vectorComponents)): vector[:, vci] = lm.u[ coef.vectorComponents[vci]].dof_last_last[:] p0.domain.PUMIMesh.transferFieldToPUMI( coef.vectorName.encode('utf-8') + b"_old_old", vector) del vector for ci in range(coef.nc): if coef.vectorComponents is None or \ ci not in coef.vectorComponents: scalar = numpy.zeros((lm.mesh.nNodes_global, 1), 'd') scalar[:, 0] = lm.u[ci].dof[:] domain.PUMIMesh.transferFieldToPUMI( coef.variableNames[ci].encode('utf-8'), scalar) #Transfer dof_last scalar[:, 0] = lm.u[ci].dof_last[:] domain.PUMIMesh.transferFieldToPUMI( coef.variableNames[ci].encode('utf-8') + b"_old", scalar) #Transfer dof_last_last scalar[:, 0] = lm.u[ci].dof_last_last[:] p0.domain.PUMIMesh.transferFieldToPUMI( coef.variableNames[ci].encode('utf-8') + b"_old_old", scalar) del scalar scalar = numpy.zeros((lm.mesh.nNodes_global, 1), 'd') del scalar #Get Physical Parameters #Can we do this in a problem-independent way? rho = numpy.array([rho_0, rho_1]) nu = numpy.array([nu_0, nu_1]) g = numpy.asarray(g) #This condition is to account for adapting before the simulation started if (hasattr(self, "tn")): #deltaT = self.tn-self.tn_last #is actually the time step for next step, self.tn and self.tn_last refer to entries in tnList #deltaT = self.systemStepController.dt_system deltaT = self.modelList[0].levelModelList[0].timeIntegration.dtLast T_current = self.systemStepController.t_system_last deltaT_next = self.systemStepController.dt_system else: deltaT = 0 deltaT_next = 0.0 T_current = 0.0 epsFact = epsFact_density #domain.PUMIMesh.transferPropertiesToPUMI(rho,nu,g,deltaT,epsFact) domain.PUMIMesh.transferPropertiesToPUMI(rho_transfer, nu_transfer, g, deltaT, deltaT_next, T_current, epsFact) del rho, nu, g, epsFact