示例#1
0
    def __init__(self, heatSLE,  rtolerance=1.0e-5, **kwargs):
        if not isinstance(heatSLE, uw.systems.SteadyStateHeat):
            raise TypeError("Provided system must be of 'SteadyStateHeat' class")
        self._heatSLE=heatSLE
        self._temperatureField=heatSLE._temperatureField
        if not isinstance( heatSLE._temperatureField, uw.mesh.MeshVariable):
            raise TypeError( "Provided 'temperatureField' must be of 'MeshVariable' class." )
        # create solutions vector
        self._temperatureSol = sle.SolutionVector(heatSLE._temperatureField)
        if not isinstance(rtolerance, float):
            raise TypeError( "Provided 'rtolerance' must be of type 'float'" )
        self._rtolerance=rtolerance
        
        self.options=OptionsGroup()

        super(HeatSolver, self).__init__(**kwargs)
示例#2
0
    def __init__(self,
                 pressureField,
                 fn_diffusivity,
                 fn_bodyforce=None,
                 voronoi_swarm=None,
                 conditions=[],
                 velocityField=None,
                 swarmVarVelocity=None,
                 _removeBCs=True,
                 **kwargs):

        if not isinstance(pressureField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'pressureField' must be of 'MeshVariable' class.")
        self._pressureField = pressureField

        try:
            _fn_diffusivity = uw.function.Function.convert(fn_diffusivity)
        except Exception as e:
            raise uw._prepend_message_to_exception(
                e,
                "Exception encountered. Note that provided 'fn_diffusivity' must be of or convertible to 'Function' class.\nEncountered exception message:\n"
            )

        if not fn_bodyforce:
            if pressureField.mesh.dim == 2:
                fn_bodyforce = (0., 0.)
            else:
                fn_bodyforce = (0., 0., 0.)
        try:
            _fn_bodyforce = uw.function.Function.convert(fn_bodyforce)
        except Exception as e:
            raise uw._prepend_message_to_exception(
                e,
                "Exception encountered. Note that provided 'fn_bodyforce' must be of or convertible to 'Function' class.\nEncountered exception message:\n"
            )

        if voronoi_swarm and not isinstance(voronoi_swarm, uw.swarm.Swarm):
            raise TypeError("Provided 'swarm' must be of 'Swarm' class.")
        self._swarm = voronoi_swarm
        if len(numpy.unique(voronoi_swarm.owningCell.data[:])) != len(
                voronoi_swarm.owningCell.data[:]):
            import warnings
            warnings.warn(
                "It is not advised to fill any cell with more than one particle, as the Q1 shape function cannot capture material interfaces. Use at your own risk."
            )

        if velocityField and not isinstance(velocityField,
                                            uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'velocityField' must be of 'MeshVariable' class.")
        self._velocityField = velocityField

        if swarmVarVelocity and not isinstance(swarmVarVelocity,
                                               uw.swarm.SwarmVariable):
            raise TypeError(
                "Provided 'swarmVarVelocity' must be of 'SwarmVariable' class."
            )
        self._swarmVarVelocity = swarmVarVelocity

        if voronoi_swarm and pressureField.mesh.elementType == 'Q2':
            import warnings
            warnings.warn(
                "Voronoi integration may yield unsatisfactory results for Q2 element types. Q2 element types can also result in spurious velocity calculations."
            )

        if not isinstance(_removeBCs, bool):
            raise TypeError("Provided '_removeBCs' must be of type bool.")
        self._removeBCs = _removeBCs

        # error check dcs 'dirichlet conditions' and ncs 'neumann cond.' FeMesh_IndexSets
        nbc = None
        mesh = pressureField.mesh

        if not isinstance(conditions, (list, tuple)):
            conditionslist = []
            conditionslist.append(conditions)
            conditions = conditionslist
        for cond in conditions:
            if not isinstance(cond, uw.conditions.SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be a list 'SystemCondition' objects."
                )
            # set the bcs on here
            if type(cond) == uw.conditions.DirichletCondition:
                if cond.variable == pressureField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        pressureField._cself, cond._cself)
            elif type(cond) == uw.conditions.NeumannCondition:
                nbc = cond
            else:
                raise RuntimeError("Can't decide on input condition")

        # build the equation numbering for the temperature field discretisation
        tEqNums = self._tEqNums = sle.EqNumber(pressureField,
                                               removeBCs=self._removeBCs)

        # create solutions vector
        self._solutionVector = sle.SolutionVector(pressureField, tEqNums)
        libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector(
            self._solutionVector._cself)

        # create force vectors
        self._fvector = sle.AssembledVector(pressureField, tEqNums)

        # and matrices
        self._kmatrix = sle.AssembledMatrix(self._solutionVector,
                                            self._solutionVector,
                                            rhs=self._fvector)

        # we will use voronoi if that has been requested by the user, else use
        # gauss integration.
        if self._swarm:
            intswarm = self._swarm._voronoi_swarm
            # need to ensure voronoi is populated now, as assembly terms will call
            # initial test functions which may require a valid voronoi swarm
            self._swarm._voronoi_swarm.repopulate()
        else:
            intswarm = uw.swarm.GaussIntegrationSwarm(mesh)

        self._kMatTerm = sle.MatrixAssemblyTerm_NA_i__NB_i__Fn(
            integrationSwarm=intswarm,
            assembledObject=self._kmatrix,
            fn=_fn_diffusivity)

        self._forceVecTerm = sle.VectorAssemblyTerm_NA_i__Fn_i(
            integrationSwarm=intswarm,
            assembledObject=self._fvector,
            fn=fn_bodyforce * fn_diffusivity)

        # search for neumann conditions
        for cond in conditions:
            if isinstance(cond, uw.conditions.NeumannCondition):
                #NOTE many NeumannConditions can be used but the _sufaceFluxTerm only records the last

                ### -VE flux because of Energy_SLE_Solver ###
                negativeCond = uw.conditions.NeumannCondition(
                    fn_flux=-1.0 * cond.fn_flux,
                    variable=cond.variable,
                    indexSetsPerDof=cond.indexSet)

                self._surfaceFluxTerm = sle.VectorSurfaceAssemblyTerm_NA__Fn__ni(
                    assembledObject=self._fvector,
                    surfaceGaussPoints=2,
                    nbc=negativeCond)
        super(SteadyStateDarcyFlow, self).__init__(**kwargs)
    def __init__(self,
                 phiField,
                 phiDotField,
                 velocityField,
                 fn_diffusivity,
                 fn_sourceTerm=None,
                 conditions=[],
                 **kwargs):

        self._diffusivity = fn_diffusivity
        self._source = fn_sourceTerm

        if not isinstance(phiField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'phiField' must be of 'MeshVariable' class.")
        if phiField.data.shape[1] != 1:
            raise TypeError("Provided 'phiField' must be a scalar")
        self._phiField = phiField

        if not isinstance(phiDotField, (uw.mesh.MeshVariable, type(None))):
            raise TypeError(
                "Provided 'phiDotField' must be 'None' or of 'MeshVariable' class."
            )
        if self._phiField.data.shape != phiDotField.data.shape:
            raise TypeError(
                "Provided 'phiDotField' is not the same shape as the provided 'phiField'"
            )
        self._phiDotField = phiDotField

        # check compatibility of phiField and velocityField
        if velocityField.data.shape[1] != self._phiField.mesh.dim:
            raise TypeError(
                "Provided 'velocityField' must be the same dimensionality as the phiField's mesh"
            )
        self._velocityField = velocityField

        if not isinstance(conditions, (list, tuple)):
            conditionslist = []
            conditionslist.append(conditions)
            conditions = conditionslist

        # check input 'conditions' list is valid
        nbc = None
        for cond in conditions:
            if not isinstance(cond, uw.conditions.SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be a list 'SystemCondition' objects."
                )
            # set the bcs on here
            if type(cond) == uw.conditions.NeumannCondition:
                if nbc != None:
                    # check only one nbc condition is given in 'conditions' list
                    RuntimeError(
                        "Provided 'conditions' can only accept one NeumannConditions condition object."
                    )
            elif type(cond) == uw.conditions.DirichletCondition:
                if cond.variable == self._phiField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        self._phiField._cself, cond._cself)
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        self._phiDotField._cself, cond._cself)
            else:
                raise RuntimeError("Input condition type not recognised.")
        self._conditions = conditions

        # force removal of BCs as SUPG cannot handle leaving them in
        self._eqNumPhi = sle.EqNumber(phiField, removeBCs=True)
        self._eqNumPhiDot = sle.EqNumber(phiDotField, removeBCs=True)

        self._phiSolution = sle.SolutionVector(phiField, self._eqNumPhi)
        self._phiDotSolution = sle.SolutionVector(phiDotField,
                                                  self._eqNumPhiDot)

        # create force vectors
        self._residualVector = sle.AssembledVector(phiField, self._eqNumPhi)
        self._massVector = sle.AssembledVector(phiField, self._eqNumPhi)

        # create swarm
        self._gaussSwarm = uw.swarm.GaussIntegrationSwarm(self._phiField.mesh)

        super(AdvectionDiffusion, self).__init__(**kwargs)

        self._cself.phiVector = self._phiSolution._cself
        self._cself.phiDotVector = self._phiDotSolution._cself
示例#4
0
    def __init__(self,
                 temperatureField,
                 fn_diffusivity,
                 fn_heating=0.,
                 voronoi_swarm=None,
                 conditions=[],
                 _removeBCs=True,
                 **kwargs):

        if not isinstance(temperatureField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'temperatureField' must be of 'MeshVariable' class.")
        self._temperatureField = temperatureField

        try:
            _fn_diffusivity = uw.function.Function.convert(fn_diffusivity)
        except Exception as e:
            raise uw._prepend_message_to_exception(
                e,
                "Exception encountered. Note that provided 'fn_diffusivity' must be of or convertible to 'Function' class.\nEncountered exception message:\n"
            )

        try:
            _fn_heating = uw.function.Function.convert(fn_heating)
        except Exception as e:
            raise uw._prepend_message_to_exception(
                e,
                "Exception encountered. Note that provided 'fn_heating' must be of or convertible to 'Function' class.\nEncountered exception message:\n"
            )

        if voronoi_swarm and not isinstance(voronoi_swarm, uw.swarm.Swarm):
            raise TypeError("Provided 'swarm' must be of 'Swarm' class.")
        self._swarm = voronoi_swarm
        if voronoi_swarm and temperatureField.mesh.elementType == 'Q2':
            import warnings
            warnings.warn(
                "Voronoi integration may yield unsatisfactory results for Q2 element types."
            )

        if not isinstance(_removeBCs, bool):
            raise TypeError("Provided '_removeBCs' must be of type bool.")
        self._removeBCs = _removeBCs

        # error check dcs 'dirichlet conditions' and ncs 'neumann cond.' FeMesh_IndexSets
        nbc = None
        mesh = temperatureField.mesh

        if not isinstance(conditions, (list, tuple)):
            conditionslist = []
            conditionslist.append(conditions)
            conditions = conditionslist
        for cond in conditions:
            if not isinstance(cond, uw.conditions.SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be a list 'SystemCondition' objects."
                )
            # set the bcs on here
            if type(cond) == uw.conditions.DirichletCondition:
                if cond.variable == temperatureField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        temperatureField._cself, cond._cself)
            elif type(cond) == uw.conditions.NeumannCondition:
                nbc = cond
            else:
                raise RuntimeError("Can't decide on input condition")

        # build the equation numbering for the temperature field discretisation
        tEqNums = self._tEqNums = sle.EqNumber(temperatureField,
                                               removeBCs=self._removeBCs)

        # create solutions vector
        self._solutionVector = sle.SolutionVector(temperatureField, tEqNums)
        libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector(
            self._solutionVector._cself)

        # create force vectors
        self._fvector = sle.AssembledVector(temperatureField, tEqNums)

        # and matrices
        self._kmatrix = sle.AssembledMatrix(self._solutionVector,
                                            self._solutionVector,
                                            rhs=self._fvector)

        # we will use voronoi if that has been requested by the user, else use
        # gauss integration.
        if self._swarm:
            intswarm = self._swarm._voronoi_swarm
            # need to ensure voronoi is populated now, as assembly terms will call
            # initial test functions which may require a valid voronoi swarm
            self._swarm._voronoi_swarm.repopulate()
        else:
            intswarm = uw.swarm.GaussIntegrationSwarm(mesh)

        self._kMatTerm = sle.MatrixAssemblyTerm_NA_i__NB_i__Fn(
            integrationSwarm=intswarm,
            assembledObject=self._kmatrix,
            fn=_fn_diffusivity)
        self._forceVecTerm = sle.VectorAssemblyTerm_NA__Fn(
            integrationSwarm=intswarm,
            assembledObject=self._fvector,
            fn=fn_heating)
        # search for neumann conditions
        for cond in conditions:
            if isinstance(cond, uw.conditions.NeumannCondition):
                #NOTE many NeumannConditions can be used but the _sufaceFluxTerm only records the last

                ### -VE flux because of the FEM discretisation method of the initial equation
                negativeCond = uw.conditions.NeumannCondition(
                    fn_flux=-1.0 * cond.fn_flux,
                    variable=cond.variable,
                    indexSetsPerDof=cond.indexSetsPerDof)

                self._surfaceFluxTerm = sle.VectorSurfaceAssemblyTerm_NA__Fn__ni(
                    assembledObject=self._fvector,
                    surfaceGaussPoints=2,
                    nbc=negativeCond)
        super(SteadyStateHeat, self).__init__(**kwargs)
示例#5
0
    def __init__(self,
                 temperatureField,
                 fn_diffusivity=None,
                 fn_heating=0.,
                 swarm=None,
                 conditions=[],
                 conductivityFn=None,
                 heatingFn=None,
                 rtolerance=None,
                 **kwargs):
        if conductivityFn:
            raise RuntimeError(
                "Note that the 'conductivityFn' parameter has been renamed to 'fn_diffusivity'."
            )
        if heatingFn:
            raise RuntimeError(
                "Note that the 'heatingFn' parameter has been renamed to 'fn_heating'."
            )
        if rtolerance:
            raise RuntimeError("Note that the 'rtolerance' parameter has been removed.\n" \
                               "All solver functionality has been moved to underworld.systems.Solver.")

        if not isinstance(temperatureField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'temperatureField' must be of 'MeshVariable' class.")
        self._temperatureField = temperatureField

        if not fn_diffusivity:
            raise ValueError(
                "You must specify a diffusivity function via the 'fn_diffusivity' parameter."
            )
        try:
            _fn_diffusivity = uw.function.Function._CheckIsFnOrConvertOrThrow(
                fn_diffusivity)
        except Exception as e:
            raise uw._prepend_message_to_exception(
                e,
                "Exception encountered. Note that provided 'fn_diffusivity' must be of or convertible to 'Function' class.\nEncountered exception message:\n"
            )

        try:
            _fn_heating = uw.function.Function._CheckIsFnOrConvertOrThrow(
                fn_heating)
        except Exception as e:
            raise uw._prepend_message_to_exception(
                e,
                "Exception encountered. Note that provided 'fn_heating' must be of or convertible to 'Function' class.\nEncountered exception message:\n"
            )

        if swarm and not isinstance(swarm, uw.swarm.Swarm):
            raise TypeError("Provided 'swarm' must be of 'Swarm' class.")
        self._swarm = swarm

        if not isinstance(conditions,
                          (uw.conditions._SystemCondition, list, tuple)):
            raise TypeError(
                "Provided 'conditions' must be a list '_SystemCondition' objects."
            )
        if len(conditions) > 1:
            raise ValueError(
                "Multiple conditions are not currently supported.")
        for cond in conditions:
            if not isinstance(cond, uw.conditions._SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be a list '_SystemCondition' objects."
                )
            # set the bcs on here.. will rearrange this in future.
            if cond.variable == self._temperatureField:
                libUnderworld.StgFEM.FeVariable_SetBC(
                    self._temperatureField._cself, cond._cself)

        # ok, we've set some bcs, lets recreate eqnumbering
        libUnderworld.StgFEM._FeVariable_CreateNewEqnNumber(
            self._temperatureField._cself)
        self._conditions = conditions

        # create solutions vector
        self._temperatureSol = sle.SolutionVector(temperatureField)

        # create force vectors
        self._fvector = sle.AssembledVector(temperatureField)

        # and matrices
        self._kmatrix = sle.AssembledMatrix(temperatureField,
                                            temperatureField,
                                            rhs=self._fvector)

        # create swarm
        self._gaussSwarm = uw.swarm.GaussIntegrationSwarm(
            self._temperatureField.mesh)
        self._PICSwarm = None
        if self._swarm:
            self._PICSwarm = uw.swarm.PICIntegrationSwarm(self._swarm)

        swarmguy = self._PICSwarm
        if not swarmguy:
            swarmguy = self._gaussSwarm
        self._kMatTerm = sle.MatrixAssemblyTerm_NA_i__NB_i__Fn(
            integrationSwarm=swarmguy,
            assembledObject=self._kmatrix,
            fn=_fn_diffusivity)
        self._forceVecTerm = sle.VectorAssemblyTerm_NA__Fn(
            integrationSwarm=swarmguy,
            assembledObject=self._fvector,
            fn=fn_heating)
        super(SteadyStateHeat, self).__init__(**kwargs)
示例#6
0
    def __init__(self,
                 velocityField,
                 pressureField,
                 fn_viscosity,
                 fn_bodyforce=None,
                 fn_one_on_lambda=None,
                 fn_lambda=None,
                 fn_source=None,
                 voronoi_swarm=None,
                 conditions=[],
                 _removeBCs=True,
                 _fn_viscosity2=None,
                 _fn_director=None,
                 fn_stresshistory=None,
                 _fn_stresshistory=None,
                 **kwargs):

        # DEPRECATION ERROR
        if fn_lambda != None:
            raise TypeError(
                "The parameter 'fn_lambda' has been deprecated. It has been replaced by 'fn_one_on_lambda', a simpler input parameter."
            )

        if _fn_stresshistory:
            raise TypeError(
                "The parameter '_fn_stresshistory' has been updated to 'fn_stresshistory'."
            )

        if not isinstance(velocityField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'velocityField' must be of 'MeshVariable' class.")
        if velocityField.nodeDofCount != velocityField.mesh.dim:
            raise ValueError(
                "Provided 'velocityField' must be a vector field of same dimensionality as its mesh."
            )
        self._velocityField = velocityField
        if not isinstance(pressureField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'pressureField' must be of 'MeshVariable' class.")
        if pressureField.nodeDofCount != 1:
            raise ValueError(
                "Provided 'pressureField' must be a scalar field (ie pressureField.nodeDofCount==1)."
            )
        self._pressureField = pressureField

        _fn_viscosity = uw.function.Function.convert(fn_viscosity)
        if not isinstance(_fn_viscosity, uw.function.Function):
            raise TypeError(
                "Provided 'fn_viscosity' must be of or convertible to 'Function' class."
            )
        if _fn_viscosity2:
            _fn_viscosity2 = uw.function.Function.convert(_fn_viscosity2)
            if not isinstance(_fn_viscosity2, uw.function.Function):
                raise TypeError(
                    "Provided 'fn_viscosity2' must be of or convertible to 'Function' class."
                )

        if not isinstance(_removeBCs, bool):
            raise TypeError("Provided '_removeBCs' must be of type bool.")
        self._removeBCs = _removeBCs

        if _fn_director:
            _fn_director = uw.function.Function.convert(_fn_director)
            if not isinstance(_fn_director, uw.function.Function):
                raise TypeError(
                    "Provided 'fn_director' must be of or convertible to 'Function' class."
                )

        if fn_stresshistory:
            fn_stresshistory = uw.function.Function.convert(fn_stresshistory)
            if not isinstance(fn_stresshistory, uw.function.Function):
                raise TypeError(
                    "Provided 'fn_stresshistory' must be of or convertible to 'Function' class."
                )

        self._fn_minus_one_on_lambda = None
        if fn_one_on_lambda != None:
            self._fn_minus_one_on_lambda = uw.function.Function.convert(
                -1.0 * fn_one_on_lambda)
            if not isinstance(self._fn_minus_one_on_lambda,
                              uw.function.Function):
                raise ValueError(
                    "Provided 'fn_minus_one_on_lambda' must be of, or convertible to, the 'Function' class."
                )

        if fn_source != None:
            self._fn_source = uw.function.Function.convert(fn_source)
            if not isinstance(self._fn_source, uw.function.Function):
                raise ValueError(
                    "Provided 'fn_source' must be of, or convertible to, the 'Function' class."
                )

        if not fn_bodyforce:
            if velocityField.mesh.dim == 2:
                fn_bodyforce = (0., 0.)
            else:
                fn_bodyforce = (0., 0., 0.)
        _fn_bodyforce = uw.function.Function.convert(fn_bodyforce)

        if voronoi_swarm and not isinstance(voronoi_swarm, uw.swarm.Swarm):
            raise TypeError(
                "Provided 'voronoi_swarm' must be of 'Swarm' class.")
        self._swarm = voronoi_swarm
        if voronoi_swarm and velocityField.mesh.elementType == 'Q2':
            import warnings
            warnings.warn(
                "Voronoi integration may yield unsatisfactory results for Q2 mesh."
            )

        mesh = velocityField.mesh

        if not isinstance(conditions, (list, tuple)):
            conditionslist = []
            conditionslist.append(conditions)
            conditions = conditionslist
        for cond in conditions:
            # set the bcs on here
            if not isinstance(cond, uw.conditions.SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be 'SystemCondition' objects.")
            elif type(cond) == uw.conditions.DirichletCondition:
                if cond.variable == self._velocityField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        self._velocityField._cself, cond._cself)
                elif cond.variable == self._pressureField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        self._pressureField._cself, cond._cself)
                else:
                    raise ValueError(
                        "Provided condition does not appear to correspond to the system unknowns."
                    )

        self._conditions = conditions

        self._eqNums = dict()
        self._eqNums[velocityField] = sle.EqNumber(self._velocityField,
                                                   self._removeBCs)
        self._eqNums[pressureField] = sle.EqNumber(self._pressureField,
                                                   self._removeBCs)

        # create solutions vectors and load fevariable values onto them for best first guess
        self._velocitySol = sle.SolutionVector(velocityField,
                                               self._eqNums[velocityField])
        self._pressureSol = sle.SolutionVector(pressureField,
                                               self._eqNums[pressureField])
        libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector(
            self._velocitySol._cself)
        libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector(
            self._pressureSol._cself)

        # create force vectors
        self._fvector = sle.AssembledVector(velocityField,
                                            self._eqNums[velocityField])
        self._hvector = sle.AssembledVector(pressureField,
                                            self._eqNums[pressureField])

        # and matrices
        self._kmatrix = sle.AssembledMatrix(self._velocitySol,
                                            self._velocitySol,
                                            rhs=self._fvector)
        self._gmatrix = sle.AssembledMatrix(self._velocitySol,
                                            self._pressureSol,
                                            rhs=self._fvector,
                                            rhs_T=self._hvector)
        self._preconditioner = sle.AssembledMatrix(self._pressureSol,
                                                   self._pressureSol,
                                                   rhs=self._hvector)

        # create assembly terms which always use gauss integration
        gaussSwarm = uw.swarm.GaussIntegrationSwarm(self._velocityField.mesh)
        self._gradStiffMatTerm = sle.GradientStiffnessMatrixTerm(
            integrationSwarm=gaussSwarm, assembledObject=self._gmatrix)
        self._preCondMatTerm = sle.PreconditionerMatrixTerm(
            integrationSwarm=gaussSwarm, assembledObject=self._preconditioner)

        # for the following terms, we will use voronoi if that has been requested
        # by the user, else use gauss again.
        intswarm = gaussSwarm

        if self._swarm:
            intswarm = self._swarm._voronoi_swarm
            # need to ensure voronoi is populated now, as assembly terms will call
            # initial test functions which may require a valid voronoi swarm
            self._swarm._voronoi_swarm.repopulate()

        self._constitMatTerm = sle.ConstitutiveMatrixTerm(
            integrationSwarm=intswarm,
            assembledObject=self._kmatrix,
            fn_visc1=_fn_viscosity,
            fn_visc2=_fn_viscosity2,
            fn_director=_fn_director)

        self._forceVecTerm = sle.VectorAssemblyTerm_NA__Fn(
            integrationSwarm=intswarm,
            assembledObject=self._fvector,
            fn=_fn_bodyforce)

        if fn_source:
            self._cforceVecTerm = sle.VectorAssemblyTerm_NA__Fn(
                integrationSwarm=intswarm,
                assembledObject=self._hvector,
                fn=self.fn_source)

        for cond in self._conditions:
            if isinstance(cond, uw.conditions.NeumannCondition):
                #NOTE many NeumannConditions can be used but the _sufaceFluxTerm only records the last
                self._surfaceFluxTerm = sle.VectorSurfaceAssemblyTerm_NA__Fn__ni(
                    assembledObject=self._fvector,
                    surfaceGaussPoints=
                    3,  # increase to resolve stress bc fluctuations
                    nbc=cond)
        if self._fn_minus_one_on_lambda != None:
            # add matrix and associated assembly term for compressible stokes formulation
            # a mass matrix goes into the lower right block of the stokes system coeff matrix
            self._mmatrix = sle.AssembledMatrix(self._pressureSol,
                                                self._pressureSol,
                                                rhs=self._hvector)
            # -1. as per Hughes, The Finite Element Method, 1987, Table 4.3.1, [M]

            self._compressibleTerm = sle.MatrixAssemblyTerm_NA__NB__Fn(
                integrationSwarm=intswarm,
                assembledObject=self._mmatrix,
                mesh=self._velocityField.mesh,
                fn=self._fn_minus_one_on_lambda)

        if fn_stresshistory != None:
            self._NA_j__Fn_ijTerm = sle.VectorAssemblyTerm_NA_j__Fn_ij(
                integrationSwarm=intswarm,
                assembledObject=self._fvector,
                fn=fn_stresshistory)

        super(Stokes, self).__init__(**kwargs)
示例#7
0
    def __init__(self,
                 velocityField,
                 pressureField,
                 fn_viscosity=None,
                 fn_bodyforce=None,
                 swarm=None,
                 conditions=[],
                 viscosityFn=None,
                 bodyForceFn=None,
                 rtolerance=None,
                 **kwargs):
        # DEPRECATE 1/16
        if viscosityFn:
            raise RuntimeError(
                "Note that the 'viscosityFn' parameter has been renamed to 'fn_viscosity'."
            )
        if bodyForceFn:
            raise RuntimeError(
                "Note that the 'bodyForceFn' parameter has been renamed to 'fn_bodyforce'."
            )
        if rtolerance:
            raise RuntimeError("Note that the 'rtolerance' parameter has been removed.\n" \
                               "All solver functionality has been moved to underworld.systems.Solver.")

        if not isinstance(velocityField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'velocityField' must be of 'MeshVariable' class.")
        if velocityField.nodeDofCount != velocityField.mesh.dim:
            raise ValueError(
                "Provided 'velocityField' must be a vector field of same dimensionality as its mesh."
            )
        self._velocityField = velocityField
        if not isinstance(pressureField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'pressureField' must be of 'MeshVariable' class.")
        if pressureField.nodeDofCount != 1:
            raise ValueError(
                "Provided 'pressureField' must be a scalar field (ie pressureField.nodeDofCount==1)."
            )
        self._pressureField = pressureField

        if not fn_viscosity:
            raise ValueError(
                "You must specify a viscosity function via the 'fn_viscosity' parameter."
            )
        _fn_viscosity = uw.function.Function._CheckIsFnOrConvertOrThrow(
            fn_viscosity)
        if not isinstance(_fn_viscosity, uw.function.Function):
            raise TypeError(
                "Provided 'fn_viscosity' must be of or convertible to 'Function' class."
            )

        if not fn_bodyforce:
            if velocityField.mesh.dim == 2:
                fn_bodyforce = (0., 0.)
            else:
                fn_bodyforce = (0., 0., 0.)
        _fn_bodyforce = uw.function.Function._CheckIsFnOrConvertOrThrow(
            fn_bodyforce)

        if swarm and not isinstance(swarm, uw.swarm.Swarm):
            raise TypeError("Provided 'swarm' must be of 'Swarm' class.")
        self._swarm = swarm

        if not isinstance(conditions,
                          (uw.conditions._SystemCondition, list, tuple)):
            raise TypeError(
                "Provided 'conditions' must be a list '_SystemCondition' objects."
            )
        if len(conditions) > 1:
            raise ValueError(
                "Multiple conditions are not currently supported.")
        for cond in conditions:
            if not isinstance(cond, uw.conditions._SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be a list '_SystemCondition' objects."
                )
            # set the bcs on here.. will rearrange this in future.
            if cond.variable == self._velocityField:
                libUnderworld.StgFEM.FeVariable_SetBC(
                    self._velocityField._cself, cond._cself)
            elif cond.variable == self._pressureField:
                libUnderworld.StgFEM.FeVariable_SetBC(
                    self._pressureField._cself, cond._cself)
            else:
                raise ValueError(
                    "Condition object does not appear to apply to the provided velocityField or pressureField."
                )

        # ok, we've set some bcs, lets recreate eqnumbering
        libUnderworld.StgFEM._FeVariable_CreateNewEqnNumber(
            self._pressureField._cself)
        libUnderworld.StgFEM._FeVariable_CreateNewEqnNumber(
            self._velocityField._cself)
        self._conditions = conditions

        # create solutions vectors
        self._velocitySol = sle.SolutionVector(velocityField)
        self._pressureSol = sle.SolutionVector(pressureField)

        # create force vectors
        self._fvector = sle.AssembledVector(velocityField)
        self._hvector = sle.AssembledVector(pressureField)

        # and matrices
        self._kmatrix = sle.AssembledMatrix(velocityField,
                                            velocityField,
                                            rhs=self._fvector)
        self._gmatrix = sle.AssembledMatrix(velocityField,
                                            pressureField,
                                            rhs=self._fvector,
                                            rhs_T=self._hvector)
        self._preconditioner = sle.AssembledMatrix(pressureField,
                                                   pressureField,
                                                   rhs=self._hvector,
                                                   allowZeroContrib=True)

        # create swarm
        self._gaussSwarm = uw.swarm.GaussIntegrationSwarm(
            self._velocityField.mesh)
        self._PICSwarm = None
        if self._swarm:
            self._PICSwarm = uw.swarm.PICIntegrationSwarm(self._swarm)
            self._PICSwarm.repopulate()
        # create assembly terms
        self._gradStiffMatTerm = sle.GradientStiffnessMatrixTerm(
            integrationSwarm=self._gaussSwarm, assembledObject=self._gmatrix)
        self._preCondMatTerm = sle.PreconditionerMatrixTerm(
            integrationSwarm=self._gaussSwarm,
            assembledObject=self._preconditioner)

        swarmguy = self._PICSwarm
        if not swarmguy:
            swarmguy = self._gaussSwarm
        self._constitMatTerm = sle.ConstitutiveMatrixTerm(
            integrationSwarm=swarmguy,
            assembledObject=self._kmatrix,
            fn=_fn_viscosity)
        self._forceVecTerm = sle.VectorAssemblyTerm_NA__Fn(
            integrationSwarm=swarmguy,
            assembledObject=self._fvector,
            fn=_fn_bodyforce)
        super(Stokes, self).__init__(**kwargs)
示例#8
0
    def __init__(self,
                 velocityField,
                 pressureField,
                 fn_viscosity,
                 fn_bodyforce=None,
                 fn_lambda=None,
                 voronoi_swarm=None,
                 conditions=[],
                 _removeBCs=True,
                 _fn_viscosity2=None,
                 _fn_director=None,
                 _fn_stresshistory=None,
                 **kwargs):

        if not isinstance(velocityField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'velocityField' must be of 'MeshVariable' class.")
        if velocityField.nodeDofCount != velocityField.mesh.dim:
            raise ValueError(
                "Provided 'velocityField' must be a vector field of same dimensionality as its mesh."
            )
        self._velocityField = velocityField
        if not isinstance(pressureField, uw.mesh.MeshVariable):
            raise TypeError(
                "Provided 'pressureField' must be of 'MeshVariable' class.")
        if pressureField.nodeDofCount != 1:
            raise ValueError(
                "Provided 'pressureField' must be a scalar field (ie pressureField.nodeDofCount==1)."
            )
        self._pressureField = pressureField

        _fn_viscosity = uw.function.Function.convert(fn_viscosity)
        if not isinstance(_fn_viscosity, uw.function.Function):
            raise TypeError(
                "Provided 'fn_viscosity' must be of or convertible to 'Function' class."
            )
        if _fn_viscosity2:
            _fn_viscosity2 = uw.function.Function.convert(_fn_viscosity2)
            if not isinstance(_fn_viscosity2, uw.function.Function):
                raise TypeError(
                    "Provided 'fn_viscosity2' must be of or convertible to 'Function' class."
                )

        if not isinstance(_removeBCs, bool):
            raise TypeError("Provided '_removeBCs' must be of type bool.")
        self._removeBCs = _removeBCs

        if _fn_director:
            _fn_director = uw.function.Function.convert(_fn_director)
            if not isinstance(_fn_director, uw.function.Function):
                raise TypeError(
                    "Provided 'fn_director' must be of or convertible to 'Function' class."
                )

        if _fn_stresshistory:
            _fn_stresshistory = uw.function.Function.convert(_fn_stresshistory)
            if not isinstance(_fn_stresshistory, uw.function.Function):
                raise TypeError(
                    "Provided '_fn_stresshistory' must be of or convertible to 'Function' class."
                )

        if fn_lambda != None:
            fn_lambda = uw.function.Function.convert(fn_lambda)
            if not isinstance(fn_lambda, uw.function.Function):
                raise ValueError(
                    "Provided 'fn_lambda' must be of, or convertible to, the 'Function' class."
                )

        if not fn_bodyforce:
            if velocityField.mesh.dim == 2:
                fn_bodyforce = (0., 0.)
            else:
                fn_bodyforce = (0., 0., 0.)
        _fn_bodyforce = uw.function.Function.convert(fn_bodyforce)

        if voronoi_swarm and not isinstance(voronoi_swarm, uw.swarm.Swarm):
            raise TypeError(
                "Provided 'voronoi_swarm' must be of 'Swarm' class.")
        self._swarm = voronoi_swarm
        if voronoi_swarm and velocityField.mesh.elementType == 'Q2':
            import warnings
            warnings.warn(
                "Voronoi integration may yield unsatisfactory results for Q2 mesh."
            )

        mesh = velocityField.mesh

        if not isinstance(conditions, (list, tuple)):
            conditionslist = []
            conditionslist.append(conditions)
            conditions = conditionslist
        for cond in conditions:
            # set the bcs on here
            if not isinstance(cond, uw.conditions.SystemCondition):
                raise TypeError(
                    "Provided 'conditions' must be 'SystemCondition' objects.")
            elif type(cond) == uw.conditions.DirichletCondition:
                if cond.variable == self._velocityField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        self._velocityField._cself, cond._cself)
                if cond.variable == self._pressureField:
                    libUnderworld.StgFEM.FeVariable_SetBC(
                        self._pressureField._cself, cond._cself)

        self._conditions = conditions

        self._eqNums = dict()
        self._eqNums[velocityField] = sle.EqNumber(self._velocityField,
                                                   self._removeBCs)
        self._eqNums[pressureField] = sle.EqNumber(self._pressureField,
                                                   self._removeBCs)

        # create solutions vectors and load fevariable values onto them for best first guess
        self._velocitySol = sle.SolutionVector(velocityField,
                                               self._eqNums[velocityField])
        self._pressureSol = sle.SolutionVector(pressureField,
                                               self._eqNums[pressureField])
        libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector(
            self._velocitySol._cself)
        libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector(
            self._pressureSol._cself)

        # create force vectors
        self._fvector = sle.AssembledVector(velocityField,
                                            self._eqNums[velocityField])
        self._hvector = sle.AssembledVector(pressureField,
                                            self._eqNums[pressureField])

        # and matrices
        self._kmatrix = sle.AssembledMatrix(self._velocitySol,
                                            self._velocitySol,
                                            rhs=self._fvector)
        self._gmatrix = sle.AssembledMatrix(self._velocitySol,
                                            self._pressureSol,
                                            rhs=self._fvector,
                                            rhs_T=self._hvector)
        self._preconditioner = sle.AssembledMatrix(self._pressureSol,
                                                   self._pressureSol,
                                                   rhs=self._hvector)
        if fn_lambda != None:
            self._mmatrix = sle.AssembledMatrix(self._pressureSol,
                                                self._pressureSol,
                                                rhs=self._hvector)

        # create assembly terms which always use gauss integration
        gaussSwarm = uw.swarm.GaussIntegrationSwarm(self._velocityField.mesh)
        self._gradStiffMatTerm = sle.GradientStiffnessMatrixTerm(
            integrationSwarm=gaussSwarm, assembledObject=self._gmatrix)
        self._preCondMatTerm = sle.PreconditionerMatrixTerm(
            integrationSwarm=gaussSwarm, assembledObject=self._preconditioner)

        # for the following terms, we will use voronoi if that has been requested
        # by the user, else use gauss again.
        intswarm = gaussSwarm
        if self._swarm:
            intswarm = self._swarm._voronoi_swarm
            # need to ensure voronoi is populated now, as assembly terms will call
            # initial test functions which may require a valid voronoi swarm
            self._swarm._voronoi_swarm.repopulate()

        self._constitMatTerm = sle.ConstitutiveMatrixTerm(
            integrationSwarm=intswarm,
            assembledObject=self._kmatrix,
            fn_visc1=_fn_viscosity,
            fn_visc2=_fn_viscosity2,
            fn_director=_fn_director)
        self._forceVecTerm = sle.VectorAssemblyTerm_NA__Fn(
            integrationSwarm=intswarm,
            assembledObject=self._fvector,
            fn=_fn_bodyforce)
        for cond in self._conditions:
            if isinstance(cond, uw.conditions.NeumannCondition):
                #NOTE many NeumannConditions can be used but the _sufaceFluxTerm only records the last
                self._surfaceFluxTerm = sle.VectorSurfaceAssemblyTerm_NA__Fn__ni(
                    assembledObject=self._fvector,
                    surfaceGaussPoints=
                    3,  # increase to resolve stress bc fluctuations
                    nbc=cond)
        if fn_lambda != None:
            # some logic for constructing the lower-right [2,2] matrix in the stokes system
            # [M] = [Na * 1.0/fn_lambda * Nb], where in our formulation Na and Nb are the pressure shape functions.
            # see 4.3.21 of Hughes, Linear static and dynamic finite element analysis

            # If fn_lambda is negligable, ie <1.0e-8, then we set the entry to 0.0, ie, incompressible
            # otherwise we provide 1.0/lambda to [M]

            logicFn = uw.function.branching.conditional([(fn_lambda > 1.0e-8,
                                                          1.0 / fn_lambda),
                                                         (True, 0.)])

            self._compressibleTerm = sle.MatrixAssemblyTerm_NA__NB__Fn(
                integrationSwarm=intswarm,
                assembledObject=self._mmatrix,
                mesh=self._velocityField.mesh,
                fn=logicFn)

        if _fn_stresshistory != None:
            self._vepTerm = sle.VectorAssemblyTerm_VEP__Fn(
                integrationSwarm=intswarm,
                assembledObject=self._fvector,
                fn=_fn_stresshistory)

        super(Stokes, self).__init__(**kwargs)