def get_dirichlet_boundary_conditions(self):
      """ Create and return all the strong Dirichlet boundary conditions for the Velocity and FreeSurfacePerturbation fields """
      
      # Is the Velocity field represented by a discontinous function space?
      dg = (self.W.sub(0).ufl_element().family() == "Discontinuous Lagrange")
      
      LOG.info("Preparing strong Dirichlet boundary conditions...")
      bcs = []
      bc_expressions = []
      for i in range(0, libspud.option_count("/system/core_fields/vector_field::Velocity/boundary_condition")):
         if(libspud.have_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet" % i) and
            not libspud.have_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet/apply_weakly" % i)):
            expr = ExpressionFromOptions(path = ("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet" % i), t=0).get_expression()
            # Surface IDs on the domain boundary
            surface_ids = libspud.get_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/surface_ids" % i)
            method = ("geometric" if dg else "topological")
            bc = DirichletBC(self.W.sub(0), expr, surface_ids, method=method)
            bcs.append(bc)
            bc_expressions.append(expr)
            LOG.debug("Applying Velocity BC #%d strongly to surface IDs: %s" % (i, surface_ids))

      for i in range(0, libspud.option_count("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition/type::dirichlet")):
         if(libspud.have_option("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet" % i) and
            not(libspud.have_option("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet/apply_weakly" % i))):
            expr = ExpressionFromOptions(path = ("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet" % i), t=0).get_expression()
            # Surface IDs on the domain boundary
            surface_ids = libspud.get_option("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/surface_ids" % i)
            method = ("geometric" if dg else "topological")
            bc = DirichletBC(self.W.sub(1), expr, surface_ids, method=method)
            bcs.append(bc)
            bc_expressions.append(expr)
            LOG.debug("Applying FreeSurfacePerturbation BC #%d strongly to surface IDs: %s" % (i, surface_ids))
            
      return bcs, bc_expressions
Example #2
0
  def fill(self):
    """Fill a bucket class with data describing a set of mixedfunctionspace systems using libspud, the given optionpath."""

    self.meshes = {}
    # loop over the meshes in the options tree
    for i in range(libspud.option_count("/geometry/mesh")):
      mesh_optionpath = "/geometry/mesh["+`i`+"]"
      mesh_name = libspud.get_option(mesh_optionpath+"/name")
      self.meshes[mesh_name] = libspud.get_option(mesh_optionpath+"/source/cell")

    visualization_optionpath = "/io/visualization/element"
    self.viselementfamily = libspud.get_option(visualization_optionpath+"/family")
    self.viselementdegree = libspud.get_option(visualization_optionpath+"/degree")

    parameters_optionpath = "/global_parameters/ufl"
    if libspud.have_option(parameters_optionpath):
      self.parameters = libspud.get_option(parameters_optionpath)

    self.systems = []
    # loop over the systems in the options tree
    for i in range(libspud.option_count("/system")):
      system_optionpath = "/system["+`i`+"]"
      system = buckettools.spud.SpudSystemBucket()
      # get all the information about this system from the options dictionary
      system.fill(system_optionpath, self)
      # let the bucket know about this system
      self.systems.append(system)
      # done with this system
      del system
Example #3
0
    def get_inlets(self):
        """ Wrap the inlet data into a class """

        inlets = []

        options_base = '/embedded_models/particle_model/inlet'

        for _ in range(libspud.option_count(options_base)):
            val = None
            options_key = options_base +'[%s]'%_
            surface_ids = libspud.get_option(options_key+'/surface_ids')
            insertion_rate = libspud.get_option(options_key+'/insertion_rate')
            if libspud.have_option(options_key+'/particle_velocity/constant'):
                rvel = libspud.get_option(options_key+'/particle_velocity/constant')
                velocity = lambda x, t: rvel
            elif libspud.have_option(options_key+'/particle_velocity/fluid_velocity'):
                velocity = None
            else:
                exec(libspud.get_option(options_key+'/particle_velocity/python')) in globals(), locals()
                velocity = val
            if libspud.have_option(options_key+'/probability_density_function/constant'):
                rpdf = libspud.get_option(options_key+'/probability_density_function/constant')
                pdf = lambda x, t: rpdf
            elif libspud.have_option(options_key+'/probability_density_function/fluid_velocity'):
                pdf = None
            else:
                exec(libspud.get_option(options_key+'/probability_density_function/python')) in globals(), locals()
                pdf = val

            inlets.append(Inlet(surface_ids, insertion_rate, velocity, pdf))

        return inlets
 def compute_diagnostics(self):
    diagnostic_field_count = libspud.option_count("/system/diagnostic_fields/diagnostic")
    if(diagnostic_field_count == 0):
       return
       
    LOG.info("Computing diagnostic fields...")
    d = Diagnostics(self.mesh)
    for i in range(0, diagnostic_field_count):
       name = libspud.get_option("/system/diagnostic_fields/diagnostic[%d]/name" % i)
       try:
          if(name == "grid_reynolds_number"):
             viscosity = Function(self.W.sub(1)).interpolate(Expression(libspud.get_option("/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value/constant")))
             field = d.grid_reynolds_number(self.u, viscosity)
          elif(name == "courant_number"):
             field = d.courant_number(self.u, self.options["dt"])
          else:
             raise ValueError("Unknown diagnostic field: %s" % name)
       except ValueError as e:
          LOG.exception(name)
          sys.exit()
          
       LOG.info("Diagnostic results for: %s" % name)
       LOG.info("Maximum value: %f" % max(field.vector()))
       LOG.info("Maximum value: %f" % min(field.vector()))
       
    return
 def fill_subforms(self, optionpath, prefix=""):
   for i in range(libspud.option_count(optionpath+"/form")):
     form_optionpath = optionpath+"/form["+`i`+"]"
     self.form_names.append(prefix+libspud.get_option(form_optionpath+"/name"))
     self.forms.append(libspud.get_option(form_optionpath)+os.linesep)
     self.form_symbols.append(libspud.get_option(form_optionpath+"/ufl_symbol").split(os.linesep)[0])
     self.form_ranks.append(int(libspud.get_option(form_optionpath+"/rank")))
    def compute_diagnostics(self):
        diagnostic_field_count = libspud.option_count(
            "/system/diagnostic_fields/diagnostic")
        if (diagnostic_field_count == 0):
            return

        LOG.info("Computing diagnostic fields...")
        d = Diagnostics(self.mesh)
        for i in range(0, diagnostic_field_count):
            name = libspud.get_option(
                "/system/diagnostic_fields/diagnostic[%d]/name" % i)
            try:
                if (name == "grid_reynolds_number"):
                    viscosity = Function(self.W.sub(1)).interpolate(
                        Expression(
                            libspud.get_option(
                                "/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value/constant"
                            )))
                    field = d.grid_reynolds_number(self.u, viscosity)
                elif (name == "courant_number"):
                    field = d.courant_number(self.u, self.options["dt"])
                else:
                    raise ValueError("Unknown diagnostic field: %s" % name)
            except ValueError as e:
                LOG.exception(name)
                sys.exit()

            LOG.info("Diagnostic results for: %s" % name)
            LOG.info("Maximum value: %f" % max(field.vector()))
            LOG.info("Maximum value: %f" % min(field.vector()))

        return
Example #7
0
 def fill_subforms(self, optionpath, prefix=""):
     for i in range(libspud.option_count(optionpath + "/form")):
         form_optionpath = optionpath + "/form[" + ` i ` + "]"
         self.form_names.append(prefix +
                                libspud.get_option(form_optionpath +
                                                   "/name"))
         self.forms.append(libspud.get_option(form_optionpath) + os.linesep)
         self.form_symbols.append(
             libspud.get_option(form_optionpath + "/ufl_symbol").split(
                 os.linesep)[0])
         self.form_ranks.append(
             int(libspud.get_option(form_optionpath + "/rank")))
 def fill_solverforms(self, optionpath, prefix=""):
   schurpc_optionpath = optionpath+"/composite_type::schur/schur_preconditioner::user"
   if (libspud.have_option(schurpc_optionpath)):
     self.fill_subforms(schurpc_optionpath, prefix=prefix)
   
   fs_optionpath = optionpath+"/fieldsplit"
   ls_optionpath = optionpath+"/linear_solver/preconditioner"
   pc_optionpath = optionpath+"/preconditioner"
   if (libspud.have_option(fs_optionpath)):
     for i in range(libspud.option_count(fs_optionpath)):
       newoptionpath = fs_optionpath+"["+`i`+"]"
       name = libspud.get_option(newoptionpath+"/name")
       self.fill_solverforms(newoptionpath+"/linear_solver/preconditioner", prefix=prefix+name+"_")
   elif (libspud.have_option(ls_optionpath)):
     self.fill_solverforms(ls_optionpath, prefix=prefix)
   elif (libspud.have_option(pc_optionpath)):
     self.fill_solverforms(pc_optionpath, prefix=prefix)
Example #9
0
    def fill_solverforms(self, optionpath, prefix=""):
        schurpc_optionpath = optionpath + "/composite_type::schur/schur_preconditioner::user"
        if (libspud.have_option(schurpc_optionpath)):
            self.fill_subforms(schurpc_optionpath, prefix=prefix)

        fs_optionpath = optionpath + "/fieldsplit"
        ls_optionpath = optionpath + "/linear_solver/preconditioner"
        pc_optionpath = optionpath + "/preconditioner"
        if (libspud.have_option(fs_optionpath)):
            for i in range(libspud.option_count(fs_optionpath)):
                newoptionpath = fs_optionpath + "[" + ` i ` + "]"
                name = libspud.get_option(newoptionpath + "/name")
                self.fill_solverforms(newoptionpath +
                                      "/linear_solver/preconditioner",
                                      prefix=prefix + name + "_")
        elif (libspud.have_option(ls_optionpath)):
            self.fill_solverforms(ls_optionpath, prefix=prefix)
        elif (libspud.have_option(pc_optionpath)):
            self.fill_solverforms(pc_optionpath, prefix=prefix)
   def run(self, array=None, annotate=False, checkpoint=None):
      """ Perform the simulation! """
      
      # The solution field defined on the mixed function space
      solution = Function(self.W, name="Solution", annotate=annotate)
      # The solution from the previous time-step. At t=0, this holds the initial conditions.
      solution_old = Function(self.W, name="SolutionOld", annotate=annotate)
      
      # Assign the initial condition
      initial_condition = self.get_initial_condition(checkpoint=checkpoint)
      solution_old.assign(initial_condition, annotate=annotate)

      # Get the test functions
      test_functions = TestFunctions(self.W)
      w = test_functions[0]; v = test_functions[1]
      LOG.info("Test functions created.")
      
      # These are like the TrialFunctions, but are just regular Functions here because we want to solve a non-linear problem
      # 'u' and 'h' are the velocity and free surface perturbation, respectively.
      functions = split(solution)
      u = functions[0]; h = functions[1]
      LOG.info("Trial functions created.")

      functions_old = split(solution_old)
      u_old = functions_old[0]; h_old = functions_old[1]

      # Write initial conditions to file
      LOG.info("Writing initial conditions to file...")
      self.output_functions["Velocity"].assign(solution_old.split()[0], annotate=False)
      self.output_files["Velocity"] << self.output_functions["Velocity"]
      self.output_functions["FreeSurfacePerturbation"].assign(solution_old.split()[1], annotate=False)
      self.output_files["FreeSurfacePerturbation"] << self.output_functions["FreeSurfacePerturbation"]
      
      # Construct the collection of all the individual terms in their weak form.
      LOG.info("Constructing form...")
      F = 0
      
      theta = self.options["theta"]
      dt = self.options["dt"]
      dimension = self.options["dimension"]
      g_magnitude = self.options["g_magnitude"]
      
      # Is the Velocity field represented by a discontinous function space?
      dg = (self.W.sub(0).ufl_element().family() == "Discontinuous Lagrange")

      # Mean free surface height
      h_mean = Function(self.W.sub(1), name="FreeSurfaceMean", annotate=False)
      h_mean.interpolate(ExpressionFromOptions(path = "/system/core_fields/scalar_field::FreeSurfaceMean/value").get_expression())

      # Weight u and h by theta to obtain the theta time-stepping scheme.
      assert(theta >= 0.0 and theta <= 1.0)
      LOG.info("Time-stepping scheme using theta = %g" % (theta))
      u_mid = (1.0 - theta) * u_old + theta * u
      h_mid = (1.0 - theta) * h_old + theta * h
         
      # The total height of the free surface.
      H = h_mean + h
      
      # Simple P1 function space, to be used in the stabilisation routines (if applicable).
      P1 = FunctionSpace(self.mesh, "CG", 1)
      cellsize = CellSize(self.mesh)

      # Normal vector to each element facet
      n = FacetNormal(self.mesh)
      
      # Mass term
      if(self.options["have_momentum_mass"]):
         LOG.debug("Momentum equation: Adding mass term...")
         M_momentum = (1.0/dt)*(inner(w, u) - inner(w, u_old))*dx
         F += M_momentum
      
      # Advection term
      if(self.options["have_momentum_advection"]):
         LOG.debug("Momentum equation: Adding advection term...")

         if(self.options["integrate_advection_term_by_parts"]):
            outflow = (dot(u_mid, n) + abs(dot(u_mid, n)))/2.0

            A_momentum = -inner(dot(u_mid, grad(w)), u_mid)*dx - inner(dot(u_mid, grad(u_mid)), w)*dx
            A_momentum += inner(w, outflow*u_mid)*ds
            if(dg):
               # Only add interior facet integrals if we are dealing with a discontinous Galerkin discretisation.
               A_momentum += dot(outflow('+')*u_mid('+') - outflow('-')*u_mid('-'), jump(w))*dS

         else:
            A_momentum = inner(dot(grad(u_mid), u_mid), w)*dx
         F += A_momentum
         
      # Viscous stress term. Note that the viscosity is kinematic (not dynamic).
      if(self.options["have_momentum_stress"]):
         LOG.debug("Momentum equation: Adding stress term...")
         
         viscosity = Function(self.W.sub(1))
         
         # Background viscosity
         background_viscosity = Function(self.W.sub(1)).interpolate(Expression(libspud.get_option("/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value/constant")))
         viscosity.assign(background_viscosity)

         # Eddy viscosity
         if(self.options["have_turbulence_parameterisation"]):
            LOG.debug("Momentum equation: Adding turbulence parameterisation...")
            base_option_path = "/system/equations/momentum_equation/turbulence_parameterisation"
            # Large eddy simulation (LES)
            if(libspud.have_option(base_option_path + "/les")):
               
               density = Constant(1.0) # We divide through by density in the momentum equation, so just set this to 1.0 for now.
               smagorinsky_coefficient = Constant(libspud.get_option(base_option_path + "/les/smagorinsky/smagorinsky_coefficient"))
               les = LES(self.mesh, self.W.sub(1), u_mid, density, smagorinsky_coefficient)

               # Add on eddy viscosity
               viscosity += les.eddy_viscosity

         # Stress tensor: tau = grad(u) + transpose(grad(u)) - (2/3)*div(u)
         if(not dg):
            # Perform a double dot product of the stress tensor and grad(w).
            K_momentum = -viscosity*inner(grad(u_mid) + grad(u_mid).T, grad(w))*dx
            K_momentum += viscosity*(2.0/3.0)*inner(div(u_mid)*Identity(dimension), grad(w))*dx
         else:
            # Interior penalty method
            cellsize = Constant(0.2) # In general, we should use CellSize(self.mesh) instead.
            alpha = 1/cellsize # Penalty parameter.
            
            K_momentum = -viscosity('+')*inner(grad(u_mid), grad(w))*dx
            for dim in range(self.options["dimension"]):
               K_momentum += -viscosity('+')*(alpha('+')/cellsize('+'))*dot(jump(w[dim], n), jump(u_mid[dim], n))*dS
               K_momentum += viscosity('+')*dot(avg(grad(w[dim])), jump(u_mid[dim], n))*dS + viscosity('+')*dot(jump(w[dim], n), avg(grad(u_mid[dim])))*dS

         F -= K_momentum # Negative sign here because we are bringing the stress term over from the RHS.

      # The gradient of the height of the free surface, h
      LOG.debug("Momentum equation: Adding gradient term...")
      C_momentum = -g_magnitude*inner(w, grad(h_mid))*dx
      F -= C_momentum
      
      # Quadratic drag term in the momentum equation
      if(self.options["have_drag"]):
         LOG.debug("Momentum equation: Adding drag term...")
         
         base_option_path = "/system/equations/momentum_equation/drag_term"
         
         # Get the bottom drag/friction coefficient.
         LOG.debug("Momentum equation: Adding bottom drag contribution...")
         bottom_drag = ExpressionFromOptions(path=base_option_path+"/scalar_field::BottomDragCoefficient/value", t=0).get_expression()
         bottom_drag = Function(self.W.sub(1)).interpolate(bottom_drag)
         
         # Magnitude of the velocity field
         magnitude = sqrt(dot(u_old, u_old))
         
         # Form the drag term
         if(array):
            LOG.debug("Momentum equation: Adding turbine drag contribution...")
            drag_coefficient = bottom_drag + array.turbine_drag()
         else:
            drag_coefficient = bottom_drag
         D_momentum = -inner(w, (drag_coefficient*magnitude/H)*u_mid)*dx
         F -= D_momentum
      
      # The mass term in the shallow water continuity equation 
      # (i.e. an advection equation for the free surface height, h)
      if(self.options["have_continuity_mass"]):
         LOG.debug("Continuity equation: Adding mass term...")
         M_continuity = (1.0/dt)*(inner(v, h) - inner(v, h_old))*dx
         F += M_continuity

      # Append any Expression objects for weak BCs here.
      weak_bc_expressions = []
      
      # Divergence term in the shallow water continuity equation
      LOG.debug("Continuity equation: Adding divergence term...")
      if(self.options["integrate_continuity_equation_by_parts"]):
         LOG.debug("The divergence term is being integrated by parts.")
         Ct_continuity = - H*inner(u_mid, grad(v))*dx
         if(dg):
            Ct_continuity += inner(jump(v, n), avg(H*u_mid))*dS
                           
         # Add in the surface integrals, but check to see if any boundary conditions need to be applied weakly here.
         boundary_markers = self.mesh.exterior_facets.unique_markers
         for marker in boundary_markers:
            marker = int(marker) # ds() will not accept markers of type 'numpy.int32', so convert it to type 'int' here.
            
            bc_type = None
            for i in range(0, libspud.option_count("/system/core_fields/vector_field::Velocity/boundary_condition")):
               bc_path = "/system/core_fields/vector_field::Velocity/boundary_condition[%d]" % i
               if(not (marker in libspud.get_option(bc_path + "/surface_ids"))):
                  # This BC is not associated with this marker, so skip it.
                  continue
                  
               # Determine the BC type.
               if(libspud.have_option(bc_path + "/type::no_normal_flow")):
                  bc_type = "no_normal_flow"
               elif(libspud.have_option(bc_path + "/type::dirichlet")):
                  if(libspud.have_option(bc_path + "/type::dirichlet/apply_weakly")):
                     bc_type = "weak_dirichlet"
                  else:
                     bc_type = "dirichlet"
               elif(libspud.have_option(bc_path + "/type::flather")):
                  bc_type = "flather"
                  
               # Apply the boundary condition...
               try:
                  LOG.debug("Applying Velocity BC of type '%s' to surface ID %d..." % (bc_type, marker))
                  if(bc_type == "flather"):
                     # The known exterior value for the Velocity.
                     u_ext = ExpressionFromOptions(path = (bc_path + "/type::flather/exterior_velocity"), t=0).get_expression()
                     Ct_continuity += H*inner(Function(self.W.sub(0)).interpolate(u_ext), n)*v*ds(int(marker))
                     
                     # The known exterior value for the FreeSurfacePerturbation.
                     h_ext = ExpressionFromOptions(path = (bc_path + "/type::flather/exterior_free_surface_perturbation"), t=0).get_expression()
                     Ct_continuity += H*sqrt(g_magnitude/H)*(h_mid - Function(self.W.sub(1)).interpolate(h_ext))*v*ds(int(marker))
                     
                     weak_bc_expressions.append(u_ext)
                     weak_bc_expressions.append(h_ext)
                     
                  elif(bc_type == "weak_dirichlet"):
                     u_bdy = ExpressionFromOptions(path = (bc_path + "/type::dirichlet"), t=0).get_expression()
                     Ct_continuity += H*(dot(Function(self.W.sub(0)).interpolate(u_bdy), n))*v*ds(int(marker))
                     
                     weak_bc_expressions.append(u_bdy)
                     
                  elif(bc_type == "dirichlet"):
                     # Add in the surface integral as it is here. The BC will be applied strongly later using a DirichletBC object.
                     Ct_continuity += H * inner(u_mid, n) * v * ds(int(marker))
                  elif(bc_type == "no_normal_flow"):
                     # Do nothing here since dot(u, n) is zero.
                     continue
                  else:
                     raise ValueError("Unknown boundary condition type!")
                     
               except ValueError as e:
                  LOG.exception(e)
                  sys.exit()
                  
            # If no boundary condition has been applied, include the surface integral as it is.
            if(bc_type is None):
               Ct_continuity += H * inner(u_mid, n) * v * ds(int(marker))

      else:
         Ct_continuity = inner(v, div(H*u_mid))*dx
      F += Ct_continuity

      # Add in any source terms
      if(self.options["have_momentum_source"]):
         LOG.debug("Momentum equation: Adding source term...")
         momentum_source_expression = ExpressionFromOptions(path = "/system/equations/momentum_equation/source_term/vector_field::Source/value", t=0).get_expression()
         momentum_source_function = Function(self.W.sub(0), annotate=False)
         F -= inner(w, momentum_source_function.interpolate(momentum_source_expression))*dx

      if(self.options["have_continuity_source"]):
         LOG.debug("Continuity equation: Adding source term...")
         continuity_source_expression = ExpressionFromOptions(path = "/system/equations/continuity_equation/source_term/scalar_field::Source/value", t=0).get_expression()
         continuity_source_function = Function(self.W.sub(1), annotate=False)
         F -= inner(v, continuity_source_function.interpolate(continuity_source_expression))*dx
         
      # Add in any SU stabilisation
      if(self.options["have_su_stabilisation"]):
         LOG.debug("Momentum equation: Adding streamline-upwind stabilisation term...")
         stabilisation = Stabilisation(self.mesh, P1, cellsize)
         
         magnitude = magnitude_vector(solution_old.split()[0], P1)

         # Bound the values for the magnitude below by 1.0e-9 for numerical stability reasons.
         u_nodes = magnitude.vector()
         near_zero = numpy.array([1.0e-9 for i in range(len(u_nodes))])
         u_nodes.set_local(numpy.maximum(u_nodes.array(), near_zero))

         diffusivity = ExpressionFromOptions(path = "/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value", t=self.options["t"]).get_expression()
         diffusivity = Function(self.W.sub(1)).interpolate(diffusivity) # Background viscosity
         grid_pe = grid_peclet_number(diffusivity, magnitude, P1, cellsize)
   
         # Bound the values for grid_pe below by 1.0e-9 for numerical stability reasons. 
         grid_pe_nodes = grid_pe.vector()
         values = numpy.array([1.0e-9 for i in range(len(grid_pe_nodes))])
         grid_pe_nodes.set_local(numpy.maximum(grid_pe_nodes.array(), values))

         F += stabilisation.streamline_upwind(w, u, magnitude, grid_pe)

      LOG.info("Form construction complete.")
      
      bcs, bc_expressions = self.get_dirichlet_boundary_conditions()
      
      # Prepare solver_parameters dictionary
      solver_parameters = self.get_solver_parameters()
      
      # Construct the solver objects
      problem = NonlinearVariationalProblem(F, solution, bcs=bcs)
      solver = NonlinearVariationalSolver(problem, solver_parameters=solver_parameters)
      LOG.debug("Variational problem solver created.")

      # PETSc solver run-times
      from petsc4py import PETSc
      main_solver_stage = PETSc.Log.Stage('Main block-coupled system solve')

      total_solver_time = 0.0

      # Time-stepping parameters and constants
      T = self.options["T"]
      t = self.options["t"]

      t += dt
      iterations_since_dump = 1
      iterations_since_checkpoint = 1
       
      # The time-stepping loop
      LOG.info("Entering the time-stepping loop...")
      #if annotate: adj_start_timestep(time=t)
      
      EPSILON = 1.0e-14
      while t <= T + EPSILON: # A small value EPSILON is added here in case of round-off error.
         LOG.info("t = %g" % t)

         ## Update any time-dependent Functions and Expressions.
         
         # Re-compute the velocity magnitude and grid Peclet number fields.
         if(self.options["have_su_stabilisation"]):
            magnitude.assign(magnitude_vector(solution_old.split()[0], P1))

            # Bound the values for the magnitude below by 1.0e-9 for numerical stability reasons.
            u_nodes = magnitude.vector()
            near_zero = numpy.array([1.0e-9 for i in range(len(u_nodes))])
            u_nodes.set_local(numpy.maximum(u_nodes.array(), near_zero))
            
            grid_pe.assign(grid_peclet_number(diffusivity, magnitude, P1, cellsize))
      
            # Bound the values for grid_pe below by 1.0e-9 for numerical stability reasons. 
            grid_pe_nodes = grid_pe.vector()
            values = numpy.array([1.0e-9 for i in range(len(grid_pe_nodes))])
            grid_pe_nodes.set_local(numpy.maximum(grid_pe_nodes.array(), values))

         if(self.options["have_turbulence_parameterisation"]):
            les.solve()

         # Time-dependent source terms
         if(self.options["have_momentum_source"]):
            momentum_source_expression.t = t
            momentum_source_function.interpolate(momentum_source_expression)
         if(self.options["have_continuity_source"]):
            continuity_source_expression.t = t
            continuity_source_function.interpolate(continuity_source_expression)

         # Update any time-varying DirichletBC objects.
         for expr in bc_expressions:
            expr.t = t
         for expr in weak_bc_expressions:
            expr.t = t
         
         # Solve the system of equations!
         start_solver_time = mpi4py.MPI.Wtime()
         main_solver_stage.push()
         
         LOG.debug("Solving the system of equations...")
         solver.solve(annotate=annotate)
         main_solver_stage.pop()
         end_solver_time = mpi4py.MPI.Wtime()
         total_solver_time += (end_solver_time - start_solver_time)     

         # Write the solution to file.
         if((self.options["dump_period"] is not None) and (dt*iterations_since_dump >= self.options["dump_period"])):
            LOG.debug("Writing data to file...")
            self.output_functions["Velocity"].assign(solution.split()[0], annotate=False)
            self.output_files["Velocity"] << self.output_functions["Velocity"]
            self.output_functions["FreeSurfacePerturbation"].assign(solution.split()[1], annotate=False)
            self.output_files["FreeSurfacePerturbation"] << self.output_functions["FreeSurfacePerturbation"]
            iterations_since_dump = 0 # Reset the counter.

         # Print out the total power generated by turbines.
         if(array):
            LOG.info("Power = %.2f" % array.power(u, density=1000))
            
         # Checkpointing
         if((self.options["checkpoint_period"] is not None) and (dt*iterations_since_checkpoint >= self.options["checkpoint_period"])):
            LOG.debug("Writing checkpoint data to file...")
            solution.dat.save("checkpoint")
            iterations_since_checkpoint = 0 # Reset the counter.
            
         # Check whether a steady-state has been reached.
         if(steady_state(solution.split()[0], solution_old.split()[0], self.options["steady_state_tolerance"]) and steady_state(solution.split()[1], solution_old.split()[1], self.options["steady_state_tolerance"])):
            LOG.info("Steady-state attained. Exiting the time-stepping loop...")
            break

         self.compute_diagnostics()

         # Move to next time step
         solution_old.assign(solution, annotate=annotate)  
         #array.turbine_drag.assign(project(array.turbine_drag, array.turbine_drag.function_space(), annotate=annotate), annotate=annotate)
         t += dt
         #if annotate: adj_inc_timestep(time=t, finished=t>T)
         
         iterations_since_dump += 1
         iterations_since_checkpoint += 1
         LOG.debug("Moving to next time level...")
      
      LOG.info("Out of the time-stepping loop.")

      LOG.debug("Total solver time: %.2f" % (total_solver_time))

      return solution
Example #11
0
def convert(fluidity_options_file_path, ff_options_file_path):
   
   # Read in Fluidity simulation options
   
   libspud.clear_options()
   libspud.load_options(fluidity_options_file_path)
   
   # Simulation name
   simulation_name = libspud.get_option("/simulation_name")
   
   # Geometry
   base = "/geometry"
   dimension = libspud.get_option(base + "/dimension")
   mesh_path = libspud.get_option(base + "/mesh::CoordinateMesh/from_file/file_name") + ".msh" # FIXME: Always assumes gmsh format.
  
   # Function spaces
   velocity_function_space = FunctionSpace("/geometry", 1)
   freesurface_function_space = FunctionSpace("/geometry", 2)
    
   # Timestepping
   base = "/timestepping"
   current_time = libspud.get_option(base + "/current_time")
   timestep = libspud.get_option(base + "/timestep")
   finish_time = libspud.get_option(base + "/finish_time")

   ## Steady-state
   if(libspud.have_option(base + "/steady_state")):
      if(libspud.have_option(base + "/steady_state/tolerance")):
         steady_state = libspud.get_option(base + "/steady_state/tolerance")
      else:
         steady_state = 1e-7
   else:
      steady_state = None   

   # I/O
   base = "/io"
   dump_format = libspud.get_option(base + "/dump_format")
   if(libspud.have_option(base + "/dump_period")):
      dump_period = libspud.get_option(base + "/dump_period/constant")
   elif(libspud.have_option(base + "/dump_period_in_timesteps")):
      dump_period = libspud.get_option(base + "/dump_period_in_timesteps/constant")*timestep
   else:
      print "Unable to obtain dump_period."
      sys.exit()
      
   # Gravity
   g_magnitude = libspud.get_option("/physical_parameters/gravity/magnitude")
   
   # Velocity field (momentum equation)
   base = "/material_phase[0]/vector_field::Velocity"
   
   ## Depth (free surface mean height)
   c = libspud.get_child_name(base + "/prognostic/equation::ShallowWater/scalar_field::BottomDepth/prescribed/value::WholeMesh/", 1)
   depth = libspud.get_option(base + "/prognostic/equation::ShallowWater/scalar_field::BottomDepth/prescribed/value::WholeMesh/%s" % c)
   
   ## Bottom drag coefficient
   if(libspud.have_option(base + "/prognostic/equation::ShallowWater/bottom_drag")):
      c = libspud.get_child_name(base + "/prognostic/equation::ShallowWater/bottom_drag/scalar_field::BottomDragCoefficient/prescribed/value::WholeMesh/", 1)
      bottom_drag = libspud.get_option(base + "/prognostic/equation::ShallowWater/bottom_drag/scalar_field::BottomDragCoefficient/prescribed/value::WholeMesh/%s" % c)
   else:
      bottom_drag = None
      
   ## Viscosity
   if(libspud.have_option(base + "/prognostic/tensor_field::Viscosity")):
      viscosity = libspud.get_option(base + "/prognostic/tensor_field::Viscosity/prescribed/value::WholeMesh/anisotropic_symmetric/constant")[0][0]
   else:
      viscosity = None

   ## Momentum source
   if(libspud.have_option(base + "/prognostic/vector_field::Source")):
      c = libspud.get_child_name(base + "/prognostic/vector_field::Source/prescribed/value::WholeMesh/", 1)
      momentum_source = libspud.get_option(base + "/prognostic/vector_field::Source/prescribed/value::WholeMesh/%s" % c)
   else:
      momentum_source = None
      
   ## Initial condition
   if(libspud.have_option(base + "/prognostic/initial_condition::WholeMesh")):
      c = libspud.get_child_name(base + "/prognostic/initial_condition::WholeMesh/", 1)
      velocity_initial_condition = libspud.get_option(base + "/prognostic/initial_condition::WholeMesh/%s" % c)
   else:
      velocity_initial_condition = 0.0
      
   ## Boundary conditions
   number_of_bcs = libspud.option_count(base + "/prognostic/boundary_conditions")
   velocity_bcs = []
   for i in range(number_of_bcs):
      velocity_bcs.append(VelocityBoundaryCondition(base + "/prognostic/boundary_conditions[%d]" % i))
   
   
   # Pressure field (continuity equation)
   base = "/material_phase[0]/scalar_field::Pressure"
   integrate_by_parts = libspud.have_option(base + "/prognostic/spatial_discretisation/continuous_galerkin/integrate_continuity_by_parts")
   
   ## Initial condition
   if(libspud.have_option(base + "/prognostic/initial_condition::WholeMesh")):
      c = libspud.get_child_name(base + "/prognostic/initial_condition::WholeMesh/", 1)
      pressure_initial_condition = libspud.get_option(base + "/prognostic/initial_condition::WholeMesh/%s" % c)
   else:
      pressure_initial_condition = 0.0
      
   ## Boundary conditions
   number_of_bcs = libspud.option_count(base + "/prognostic/boundary_conditions")
   pressure_bcs = []
   for i in range(number_of_bcs):
      pressure_bcs.append(PressureBoundaryCondition(base + "/prognostic/boundary_conditions[%d]" % i))
   
   ## Continuity source
   if(libspud.have_option(base + "/prognostic/scalar_field::Source")):
      c = libspud.get_child_name(base + "/prognostic/scalar_field::Source/prescribed/value::WholeMesh/", 1)
      continuity_source = libspud.get_option(base + "/prognostic/scalar_field::Source/prescribed/value::WholeMesh/%s" % c)
   else:
      continuity_source = None
   





   
   
   # Write out to a Firedrake-Fluids simulation configuration file
   libspud.clear_options()
   
   # Create a bare-bones .swml file to add to.
   f = open(ff_options_file_path, "w")
   f.write("<?xml version='1.0' encoding='utf-8'?>\n")
   f.write("<shallow_water_options>\n")
   f.write("</shallow_water_options>\n")
   f.close()
   
   libspud.load_options(ff_options_file_path)

   # Simulation name
   libspud.set_option("/simulation_name", simulation_name)
   
   # Geometry
   base = "/geometry"
   libspud.set_option(base + "/dimension", dimension)
   libspud.set_option(base + "/mesh/from_file/relative_path", mesh_path)
   
   # Function spaces
   base = "/function_spaces"
   libspud.set_option(base + "/function_space::VelocityFunctionSpace/degree", velocity_function_space.degree)
   libspud.set_option(base + "/function_space::VelocityFunctionSpace/family", velocity_function_space.family)
   libspud.set_option(base + "/function_space::FreeSurfaceFunctionSpace/degree", freesurface_function_space.degree)
   libspud.set_option(base + "/function_space::FreeSurfaceFunctionSpace/family", freesurface_function_space.family)
   
   # I/O
   base = "/io"
   libspud.set_option(base + "/dump_format", dump_format)
   libspud.set_option(base + "/dump_period", dump_period)
   
   # Timestepping
   base = "/timestepping"
   print timestep
   libspud.set_option(base + "/current_time", current_time)
   try:
      libspud.set_option(base + "/timestep", timestep)
   except:
      pass
   libspud.set_option(base + "/finish_time", finish_time)
   
   ## Steady-state
   if(steady_state):
      libspud.set_option(base + "/steady_state/tolerance", steady_state)
      
   # Gravity
   libspud.set_option("/physical_parameters/gravity/magnitude", g_magnitude)
   
   # System/Core Fields: Velocity
   base = "/system/core_fields/vector_field::Velocity"
   
   ## Initial condition
   if(isinstance(velocity_initial_condition, str)):
      libspud.set_option(base + "/initial_condition/python", velocity_initial_condition)
   else:
      libspud.set_option(base + "/initial_condition/constant", velocity_initial_condition)
   
   ## Boundary conditions
   try:
      for i in range(len(velocity_bcs)):
         libspud.set_option(base + "/boundary_condition::%s/surface_ids" % velocity_bcs[i].name, velocity_bcs[i].surface_ids)
         libspud.set_option_attribute(base + "/boundary_condition::%s/type/name" % velocity_bcs[i].name, velocity_bcs[i].type)
         
         if(velocity_bcs[i].type == "dirichlet"):
            if(isinstance(velocity_bcs[i].value, str)):
               libspud.set_option(base + "/boundary_condition::%s/type::dirichlet/value/python" % velocity_bcs[i].name, velocity_bcs[i].value)
            else:
               libspud.set_option(base + "/boundary_condition::%s/type::dirichlet/value/constant" % velocity_bcs[i].name, velocity_bcs[i].value)
   except:
      pass

   # System/Core Fields: FreeSurfacePerturbation
   base = "/system/core_fields/scalar_field::FreeSurfacePerturbation"
   
   #FIXME: Pressure initial and boundary conditions are multiplied by 'g' in Fluidity, but not in Firedrake-Fluids.
   ## Initial condition
   if(isinstance(pressure_initial_condition, str)):
      libspud.set_option(base + "/initial_condition/python", pressure_initial_condition)
   else:
      libspud.set_option(base + "/initial_condition/constant", pressure_initial_condition)
   
   ## Boundary conditions
   try:
      for i in range(len(pressure_bcs)):
         libspud.set_option(base + "/boundary_condition::%s/surface_ids" % pressure_bcs[i].name, pressure_bcs[i].surface_ids)
         libspud.set_option(base + "/boundary_condition::%s/type/name" % pressure_bcs[i].name, pressure_bcs[i].type)
         
         if(pressure_bcs[i].type == "dirichlet"):
            if(isinstance(pressure_bcs[i].value, str)):
               libspud.set_option(base + "/boundary_condition::%s/type::dirichlet/value/python" % pressure_bcs[i].name, pressure_bcs[i].value)
            else:
               libspud.set_option(base + "/boundary_condition::%s/type::dirichlet/value/constant" % pressure_bcs[i].name, pressure_bcs[i].value)
   except:
      pass

   # System/Core Fields: FreeSurfaceMean
   base = "/system/core_fields/scalar_field::FreeSurfaceMean"
   if(isinstance(depth, str)):
      libspud.set_option(base + "/value/python", depth)
   else:
      libspud.set_option(base + "/value/constant", depth)
      
   
   # Equations: Continuity equation
   base = "/system/equations/continuity_equation"
   libspud.set_option(base + "/integrate_by_parts", integrate_by_parts)

   ## Source term
   if(continuity_source is not None):
      if(isinstance(continuity_source, str)):
         libspud.set_option(base + "/source_term/scalar_field::Source/value/python", continuity_source)
      else:
         libspud.set_option(base + "/source_term/scalar_field::Source/value/constant", continuity_source)
         
   # Equations: Momentum equation
   base = "/system/equations/momentum_equation"
   
   ## Viscosity
   if(viscosity is not None):
      if(isinstance(viscosity, str)):
         libspud.set_option(base + "/stress_term/scalar_field::Viscosity/value/python", viscosity)
      else:
         libspud.set_option(base + "/stress_term/scalar_field::Viscosity/value/constant", viscosity)

   ## Bottom drag
   if(bottom_drag is not None):
      if(isinstance(bottom_drag, str)):
         libspud.set_option(base + "/drag_term/scalar_field::BottomDragCoefficient/value/python", bottom_drag)
      else:
         libspud.set_option(base + "/drag_term/scalar_field::BottomDragCoefficient/value/constant", bottom_drag)
   
   ## Source term
   if(momentum_source is not None):
      if(isinstance(momentum_source, str)):
         libspud.set_option(base + "/source_term/vector_field::Source/value/python", momentum_source)
      else:
         libspud.set_option(base + "/source_term/vector_field::Source/value/constant", momentum_source)
   
   
   # Write all the applied options to file.
   libspud.write_options(ff_options_file_path)
   
   return
def read_in_nirom_options(path, opal_options, nirom_options, fwd_options):

    if libspud.have_option('opal_operation/nirom/snapshots_create'):
        nirom_options.snapshots.create = True
        fwd_options.exectuable = libspud.get_option(
            'opal_operation/nirom/snapshots_create/executable')
        fwd_options.path_to_results = libspud.get_option(
            'opal_operation/nirom/snapshots_create/path')
        fwd_options.input_file = libspud.get_option(
            'opal_operation/nirom/snapshots_create/input_file')
    elif libspud.have_option('opal_operation/nirom/snapshots_location'):
        nirom_options.snapshots.location = True
        fwd_options.path_to_results = libspud.get_option(
            'opal_operation/nirom/snapshots_location/path')
        fwd_options.input_file = libspud.get_option(
            'opal_operation/nirom/snapshots_location/input_file')
        if libspud.have_option(
                'opal_operation/nirom/snapshots_location/output_filebase'):
            fwd_options.results_filebase = libspud.get_option(
                'opal_operation/nirom/snapshots_location/output_filebase')
        if libspud.have_option(
                'opal_operation/nirom/snapshots_location/extension'):
            fwd_options.results_extension = libspud.get_option(
                'opal_operation/nirom/snapshots_location/extension')
        if libspud.have_option(
                'opal_operation/nirom/snapshots_location/nParameters'):
            nirom_options.snapshots.nParameters = libspud.get_option(
                'opal_operation/nirom/snapshots_location/nParameters')

    if libspud.have_option('/opal_operation/nirom/compression'):
        if libspud.have_option('/opal_operation/nirom/compression/svd_type'):
            if libspud.have_option(
                    '/opal_operation/nirom/compression/svd_type/svd_method'):
                nirom_options.compression.svd = True
            elif libspud.have_option(
                    '/opal_operation/nirom/compression/svd_type/eigh_method'):
                nirom_options.compression.eigh = True
            elif libspud.have_option(
                    '/opal_operation/nirom/compression/svd_type/DD_eigh_method'
            ):
                nirom_options.compression.DD_eigh = True
                nirom_options.compression.num_sub_base_2 = libspud.get_option(
                    '/opal_operation/nirom/compression/svd_type/DD_eigh_method/num_sub_base_2'
                )
            nFields = libspud.option_count(
                '/opal_operation/nirom/compression/svd_type/field_name')
            for ii in range(nFields):
                my_string = libspud.get_option(
                    '/opal_operation/nirom/compression/svd_type/field_name[' +
                    str(ii) + ']/name')
                nirom_options.compression.field.append(my_string)
                value_ct = 0.0
                value_nPOD = -1
                if libspud.have_option(
                        '/opal_operation/nirom/compression/svd_type/field_name['
                        + str(ii) + ']/cumulative_tol'):
                    value_ct = libspud.get_option(
                        '/opal_operation/nirom/compression/svd_type/field_name['
                        + str(ii) + ']/cumulative_tol')
                elif libspud.have_option(
                        '/opal_operation/nirom/compression/svd_type/field_name['
                        + str(ii) + ']/nPOD'):
                    value_nPOD = libspud.get_option(
                        '/opal_operation/nirom/compression/svd_type/field_name['
                        + str(ii) + ']/nPOD')
                nirom_options.compression.cumulative_tol.append(value_ct)
                nirom_options.compression.nPOD.append(value_nPOD)

            # svd_autoencoder option should go here
            if libspud.have_option(
                    '/opal_operation/nirom/compression/svd_type/svd_autoencoder'
            ):
                nirom_options.compression.svd_autoencoder = True
                nirom_options.compression.epochs = libspud.get_option(
                    '/opal_operation/nirom/compression/svd_type/svd_autoencoder/number_epochs'
                )
                nirom_options.compression.batch_size = libspud.get_option(
                    '/opal_operation/nirom/compression/svd_type/svd_autoencoder/batch_size'
                )
                nirom_options.compression.neurons_each_layer = libspud.get_option(
                    '/opal_operation/nirom/compression/svd_type/svd_autoencoder/neurons_each_layer'
                )

        elif libspud.have_option(
                '/opal_operation/nirom/compression/autoencoder_type'):
            nirom_options.compression.autoencoder = True

            nFields = libspud.option_count(
                '/opal_operation/nirom/compression/autoencoder_type/field_name'
            )
            for ii in range(nFields):
                my_string = libspud.get_option(
                    '/opal_operation/nirom/compression/autoencoder_type/field_name['
                    + str(ii) + ']/name')
                nirom_options.compression.field.append(my_string)
                batch_size = libspud.get_option(
                    '/opal_operation/nirom/compression/autoencoder_type/field_name['
                    + str(ii) + ']/batch_size')
                nirom_options.compression.batch_size.append(batch_size)
                number_epochs = libspud.get_option(
                    '/opal_operation/nirom/compression/autoencoder_type/field_name['
                    + str(ii) + ']/number_epochs')
                nirom_options.compression.epochs.append(number_epochs)
                neurons_each_layer = libspud.get_option(
                    '/opal_operation/nirom/compression/autoencoder_type/field_name['
                    + str(ii) + ']/neurons_each_layer')
                nirom_options.compression.neurons_each_layer.append(
                    neurons_each_layer)  # neurons per layer

    if libspud.have_option('/opal_operation/nirom/training'):
        if libspud.have_option('/opal_operation/nirom/training/GPR'):
            nirom_options.training.GPR = True
            nirom_options.training.GPR_scaling = libspud.get_option(
                '/opal_operation/nirom/training/GPR/scaling_bounds')
            nirom_options.training.GPR_RBF_length_scale = libspud.get_option(
                '/opal_operation/nirom/training/GPR/RBF_length_scale')
            nirom_options.training.GPR_RBF_length_bounds = libspud.get_option(
                '/opal_operation/nirom/training/GPR/RBF_length_scale_bounds')
            nirom_options.training.GPR_constant_value = libspud.get_option(
                '/opal_operation/nirom/training/GPR/constant_value')
            nirom_options.training.GPR_constant_bounds = libspud.get_option(
                '/opal_operation/nirom/training/GPR/constant_bounds')
        if libspud.have_option('/opal_operation/nirom/training/LSTM'):
            nirom_options.training.LSTM = True
        if libspud.have_option('/opal_operation/nirom/training/DD_LSTM'):
            nirom_options.training.DD_LSTM = True
            #print "LSTM not currently implemented ... aborting"
            #sys.exit(0)
        if libspud.have_option('/opal_operation/nirom/training/DD_GPR'):
            nirom_options.training.DD_GPR = True

    if libspud.have_option('opal_operation/nirom/prediction'):
        nirom_options.prediction.nTime = libspud.get_option(
            'opal_operation/nirom/prediction/nTime')

    return opal_options, nirom_options, fwd_options
def read_in_importance_map_options(path, opal_options):

    opal_options.output_filename = libspud.get_option(path + 'Output_filename')
    opal_options.executable = libspud.get_option(path + 'Executable')
    opal_options.input_file = libspud.get_option(path + 'Input_file')

    if (libspud.have_option(path + 'Time_window')):
        opal_options.time_window = libspud.get_option(path + 'Time_window')
        if (libspud.have_option(path + 'Time_window/pass_down_ginit')):
            opal_options.pass_down_ginit = True
    else:
        opal_options.time_window = 0
        opal_options.pass_down_ginit = False

    if libspud.have_option(path + 'random_seed'):
        opal_options.random_seed = 200
    else:
        opal_options.random_seed = -1

    opal_options.functional.location_of_interest = libspud.get_option(
        path + 'functional/location_of_interest')
    if libspud.have_option(path + 'functional/all_time'):
        print "has option all time"
        opal_options.functional.time = "all_time"
    else:
        opal_options.functional.time = "end_time"
    if libspud.have_option(path + 'functional/type/standard'):
        opal_options.functional.type = "standard"
    elif libspud.have_option(path + 'functional/type/geothermal_over_time'):
        opal_options.functional.type = "geothermal_over_time"
    nffields = libspud.option_count(path + 'functional/Functional_field')
    for i in range(nffields):
        temp_field = Functional_field()
        fieldpath = path + 'functional/Functional_field[' + str(i) + ']'
        temp_field.name = libspud.get_option(fieldpath + '/name')
        if libspud.have_option(fieldpath + '/phase'):
            temp_field.phase = libspud.get_option(fieldpath + '/phase')
        if (libspud.have_option(fieldpath + '/field_type/scalar_field')):
            temp_field.field_type = "scalar_field"
        elif (libspud.have_option(fieldpath + '/field_type/vector_field')):
            temp_field.field_type = "vector_field"
        elif (libspud.have_option(fieldpath + '/field_type/tensor_field')):
            temp_field.field_type = "tensor_field"
        if (libspud.have_option(fieldpath + '/mesh_type/element')):
            temp_field.mesh_type = "element"
        elif (libspud.have_option(fieldpath + '/mesh_type/node')):
            temp_field.mesh_type = "node"

        opal_options.functional.Functional_field.append(temp_field)

    if libspud.have_option(path + 'functional/square_integrand'):
        opal_options.functional.square_integrand = True
    else:
        opal_options.functional.square_integrand = False

    nfields = libspud.option_count(path + 'Field_to_study')
    for i in range(nfields):
        temp_field = Field_To_study()
        fieldpath = path + 'Field_to_study[' + str(i) + ']'
        temp_field.name = libspud.get_option(fieldpath + '/name')
        if (libspud.have_option(fieldpath + '/field_type/scalar_field')):
            temp_field.field_type = "scalar_field"
        elif (libspud.have_option(fieldpath + '/field_type/vector_field')):
            temp_field.field_type = "vector_field"
        elif (libspud.have_option(fieldpath + '/field_type/tensor_field')):
            temp_field.field_type = "tensor_field"
        else:
            if (libspud.have_option(fieldpath + '/field_type/scalar_field')):
                temp_field.field_type = "porous_scalar"
            elif (libspud.have_option(fieldpath + '/field_type/vector_field')):
                temp_field.field_type = "porous_vector"
            elif (libspud.have_option(fieldpath + '/field_type/tensor_field')):
                temp_field.field_type = "porous_tensor"

        #temp_field.location_of_interest = libspud.get_option(fieldpath+'/location_of_interest')
        temp_field.perturbations_to_do = libspud.get_option(
            fieldpath + '/perturbations_to_do')
        temp_field.parallel_processors = 1  #Serial by default
        if (libspud.have_option(fieldpath +
                                '/perturbations_to_do/parallel_processors')):
            temp_field.parallel_processors = libspud.get_option(
                fieldpath + '/perturbations_to_do/parallel_processors')
            if libspud.have_option(path + '/Number_processors/MPI_runs'):
                opal_options.MPI_runs = libspud.get_option(
                    path + '/Number_processors/MPI_runs')
                opal_options.number_processors /= opal_options.MPI_runs
        temp_field.initial_condition = libspud.have_option(
            fieldpath + '/Initial_condition')
        temp_field.boundary_condition = libspud.have_option(
            fieldpath + '/Boundary_condition')
        temp_field.source = libspud.have_option(fieldpath + '/source')
        if (libspud.have_option(fieldpath + '/Sigma')):
            temp_field.sigma = libspud.get_option(fieldpath + '/Sigma')
        else:
            temp_field.sigma = 0.01
        if (libspud.have_option(fieldpath + '/python_function')):
            temp_field.pycode = libspud.get_option(fieldpath +
                                                   '/python_function')
        temp_field.phases_to_perturb = libspud.get_option(fieldpath +
                                                          '/Phases_to_perturb')
        if libspud.have_option(fieldpath + '/stabilise_through_diagonal'):
            temp_field.diagonal_tweak = True
            temp_field.diagonal_tweak_value = libspud.get_option(
                fieldpath + '/stabilise_through_diagonal/epsilon')
            if libspud.have_option(
                    fieldpath +
                    '/stabilise_through_diagonal/constrain_evalue'):
                temp_field.diagonal_tweak_method = 'constrain_evalue'
            elif libspud.have_option(
                    fieldpath + '/stabilise_through_diagonal/add_to_diag'):
                temp_field.diagonal_tweak_method = 'add_to_diag'
            else:
                print "error, option not expected", libspud.get_option(
                    fieldpath + '/stabilise_through_diagonal/')
        else:
            # can probably remove these three lines now __init__ is working....
            temp_field.diagonal_tweak = False
            temp_field.diagonal_tweak_method = ''
            temp_field.diagonal_tweak_value = 0.0
        if libspud.have_option(fieldpath + '/Gram-Schmidt'):
            temp_field.gram_schmidt = True
        else:
            temp_field.gram_schmidt = False
        if libspud.have_option(fieldpath + '/smoothing'):
            temp_field.nSmooth = libspud.get_option(fieldpath + '/smoothing')
        else:
            temp_field.nSmooth = 0
        if libspud.have_option(fieldpath + '/use_G'):
            temp_field.use_G = True
            temp_field.threshold_use_G = libspud.get_option(fieldpath +
                                                            '/use_G')
        else:
            temp_field.use_G = False
            temp_field.threshold_use_G = -1
        opal_options.Field_To_study_list.append(temp_field)

    return opal_options
import libspud
print libspud.__file__

libspud.load_options('test.flml')

libspud.print_options()

print libspud.number_of_children('/geometry')
print libspud.get_child_name('geometry', 0)

print libspud.option_count('/problem_type')
print libspud.have_option('/problem_type')

print libspud.get_option_type('/geometry/dimension')
print libspud.get_option_type('/problem_type')

print libspud.get_option_rank('/geometry/dimension')
print libspud.get_option_rank('/physical_parameters/gravity/vector_field::GravityDirection/prescribed/value/constant')

print libspud.get_option_shape('/geometry/dimension')
print libspud.get_option_shape('/problem_type')

print libspud.get_option('/problem_type')
print libspud.get_option('/geometry/dimension')
libspud.set_option('/geometry/dimension', 3)
print libspud.get_option('/geometry/dimension')

list_path = '/material_phase::Material1/scalar_field::MaterialVolumeFraction/prognostic/boundary_conditions::LetNoOneLeave/surface_ids'
print libspud.get_option_shape(list_path)
print libspud.get_option_rank(list_path)
print libspud.get_option(list_path)
Example #15
0
  def fill(self, optionpath, bucket):
    """Fill a system class with data describing that system using libspud and the given optionpath."""
    self.name       = libspud.get_option(optionpath+"/name")
    self.optionpath = optionpath
    self.symbol     = libspud.get_option(optionpath+"/ufl_symbol").split(os.linesep)[0]
    self.bucket     = bucket

    self.mesh_name        = libspud.get_option(optionpath+"/mesh/name")
    mesh_optionpath  = "/geometry/mesh::"+self.mesh_name
    self.cell             = libspud.get_option(mesh_optionpath+"/source/cell")

    self.fields = []
    for j in range(libspud.option_count(optionpath+"/field")):
      field_optionpath = optionpath+"/field["+`j`+"]"
      field = buckettools.spud.SpudFunctionBucket()
      # get all the information about this field from the options dictionary
      field.fill(field_optionpath, self, j)
      # let the system know about this field
      self.fields.append(field)
      # remove the local copy of this field
      del field

    self.coeffs = []
    for j in range(libspud.option_count(optionpath+"/coefficient")):
      coeff_optionpath = optionpath+"/coefficient["+`j`+"]"
      coeff = buckettools.spud.SpudFunctionBucket()
      # get all the information about this coefficient from the options dictionary
      coeff.fill(coeff_optionpath, self, j)
      # let the system know about this coefficient
      self.coeffs.append(coeff)
      # remove the local copy of this coefficient
      del coeff
    
    self.special_coeffs = []
    if libspud.have_option("/timestepping"):
      coeff_optionpath = "/timestepping/timestep/coefficient::Timestep"
      coeff = buckettools.spud.SpudFunctionBucket()
      # get all the information about this coefficient from the options dictionary
      coeff.fill(coeff_optionpath, self, 0)
      # let the system know about this coefficient
      self.special_coeffs.append(coeff)
      # remove the local copy of this coefficient
      del coeff
    
    self.solvers = []
    for j in range(libspud.option_count(optionpath+"/nonlinear_solver")):
      solver_optionpath = optionpath+"/nonlinear_solver["+`j`+"]"
      solver = buckettools.spud.SpudSolverBucket()
      # get all the information about this nonlinear solver from the options dictionary
      solver.fill(solver_optionpath, self)
      # let the system know about this solver
      self.solvers.append(solver)
      # done with this nonlinear solver
      del solver

    self.functionals = []
    for j in range(libspud.option_count(optionpath+"/functional")):
      functional_optionpath = optionpath+"/functional["+`j`+"]"
      functional = buckettools.spud.SpudFunctionalBucket()
      # get all the information about this functional from the options dictionary
      functional.fill(functional_optionpath, self)
      # let the system know about this functional
      self.functionals.append(functional)
      # done with this functional
      del functional
Example #16
0
    def fill(self, optionpath, bucket):
        """Fill a system class with data describing that system using libspud and the given optionpath."""
        self.name = libspud.get_option(optionpath + "/name")
        self.optionpath = optionpath
        self.symbol = libspud.get_option(optionpath + "/ufl_symbol").split(
            os.linesep)[0]
        self.bucket = bucket

        self.mesh_name = libspud.get_option(optionpath + "/mesh/name")
        mesh_optionpath = "/geometry/mesh::" + self.mesh_name
        self.cell = libspud.get_option(mesh_optionpath + "/source/cell")

        self.fields = []
        for j in range(libspud.option_count(optionpath + "/field")):
            field_optionpath = optionpath + "/field[" + ` j ` + "]"
            field = buckettools.spud.SpudFunctionBucket()
            # get all the information about this field from the options dictionary
            field.fill(field_optionpath, self, j)
            # let the system know about this field
            self.fields.append(field)
            # remove the local copy of this field
            del field

        self.coeffs = []
        for j in range(libspud.option_count(optionpath + "/coefficient")):
            coeff_optionpath = optionpath + "/coefficient[" + ` j ` + "]"
            coeff = buckettools.spud.SpudFunctionBucket()
            # get all the information about this coefficient from the options dictionary
            coeff.fill(coeff_optionpath, self, j)
            # let the system know about this coefficient
            self.coeffs.append(coeff)
            # remove the local copy of this coefficient
            del coeff

        self.special_coeffs = []
        if libspud.have_option("/timestepping"):
            coeff_optionpath = "/timestepping/timestep/coefficient::Timestep"
            coeff = buckettools.spud.SpudFunctionBucket()
            # get all the information about this coefficient from the options dictionary
            coeff.fill(coeff_optionpath, self, 0)
            # let the system know about this coefficient
            self.special_coeffs.append(coeff)
            # remove the local copy of this coefficient
            del coeff

        self.solvers = []
        for j in range(libspud.option_count(optionpath + "/nonlinear_solver")):
            solver_optionpath = optionpath + "/nonlinear_solver[" + ` j ` + "]"
            solver = buckettools.spud.SpudSolverBucket()
            # get all the information about this nonlinear solver from the options dictionary
            solver.fill(solver_optionpath, self)
            # let the system know about this solver
            self.solvers.append(solver)
            # done with this nonlinear solver
            del solver

        self.functionals = []
        for j in range(libspud.option_count(optionpath + "/functional")):
            functional_optionpath = optionpath + "/functional[" + ` j ` + "]"
            functional = buckettools.spud.SpudFunctionalBucket()
            # get all the information about this functional from the options dictionary
            functional.fill(functional_optionpath, self)
            # let the system know about this functional
            self.functionals.append(functional)
            # done with this functional
            del functional
import libspud

libspud.load_options('test.flml')

#libspud.print_options()

assert libspud.get_option('/timestepping/timestep') == 0.025

assert libspud.get_number_of_children('/geometry') == 5
assert libspud.get_child_name('geometry', 0) == "dimension"

assert libspud.option_count('/problem_type') == 1
assert libspud.have_option('/problem_type')

assert libspud.get_option_type('/geometry/dimension') is int
assert libspud.get_option_type('/problem_type') is str

assert libspud.get_option_rank('/geometry/dimension') == 0
assert libspud.get_option_rank(
    '/physical_parameters/gravity/vector_field::GravityDirection/prescribed/value/constant'
) == 1

assert libspud.get_option_shape('/geometry/dimension') == (-1, -1)
assert libspud.get_option_shape('/problem_type')[0] > 1
assert libspud.get_option_shape('/problem_type')[1] == -1

assert libspud.get_option('/problem_type') == "multimaterial"
assert libspud.get_option('/geometry/dimension') == 2
libspud.set_option('/geometry/dimension', 3)

assert libspud.get_option('/geometry/dimension') == 3
Example #18
0
    def __init__(self,
                 tfml_file,
                 system_name='magma',
                 p_name='Pressure',
                 f_name='Porosity',
                 c_name='c',
                 n_name='n',
                 m_name='m',
                 d_name='d',
                 N_name='N',
                 h_squared_name='h_squared',
                 x0_name='x0'):
        """read the tfml_file and use libspud to populate the internal parameters

        c: wavespeed
        n: permeability exponent
        m: bulk viscosity exponent
        d: wave dimension
        N: number of collocation points
        x0: coordinate wave peak
        h_squared:  the size of the system in compaction lengths
                    squared (h/delta)**2
        """
        # initialize libspud and extract parameters
        libspud.clear_options()
        libspud.load_options(tfml_file)
        # get model dimension
        self.dim = libspud.get_option("/geometry/dimension")
        self.system_name = system_name
        # get solitary wave parameters
        path = "/system::" + system_name + "/coefficient::"
        scalar_value = "/type::Constant/rank::Scalar/value::WholeMesh/constant"
        vector_value = "/type::Constant/rank::Vector/value::WholeMesh/constant::dim"
        c = libspud.get_option(path + c_name + scalar_value)
        n = int(libspud.get_option(path + n_name + scalar_value))
        m = int(libspud.get_option(path + m_name + scalar_value))
        d = float(libspud.get_option(path + d_name + scalar_value))
        N = int(libspud.get_option(path + N_name + scalar_value))
        self.h = np.sqrt(
            libspud.get_option(path + h_squared_name + scalar_value))
        self.x0 = np.array(libspud.get_option(path + x0_name + vector_value))
        self.swave = SolitaryWave(c, n, m, d, N)
        self.rmax = self.swave.r[-1]
        self.tfml_file = tfml_file

        # check that d <= dim
        assert (d <= self.dim)

        # sort out appropriate index for calculating distance r
        if d == 1:
            self.index = [self.dim - 1]
        else:
            self.index = range(0, int(d))

        # check that the origin point is the correct dimension
        assert (len(self.x0) == self.dim)

        #read in information for constructing Function space and dolfin objects
        # get the mesh parameters and reconstruct the mesh
        meshtype = libspud.get_option("/geometry/mesh/source[0]/name")
        if meshtype == 'UnitSquare':
            number_cells = libspud.get_option(
                "/geometry/mesh[0]/source[0]/number_cells")
            diagonal = libspud.get_option(
                "/geometry/mesh[0]/source[0]/diagonal")
            mesh = df.UnitSquareMesh(number_cells[0], number_cells[1],
                                     diagonal)
        elif meshtype == 'Rectangle':
            x0 = libspud.get_option(
                "/geometry/mesh::Mesh/source::Rectangle/lower_left")
            x1 = libspud.get_option(
                "/geometry/mesh::Mesh/source::Rectangle/upper_right")
            number_cells = libspud.get_option(
                "/geometry/mesh::Mesh/source::Rectangle/number_cells")
            diagonal = libspud.get_option(
                "/geometry/mesh[0]/source[0]/diagonal")
            mesh = df.RectangleMesh(x0[0], x0[1], x1[0], x1[1],
                                    number_cells[0], number_cells[1], diagonal)
        elif meshtype == 'UnitCube':
            number_cells = libspud.get_option(
                "/geometry/mesh[0]/source[0]/number_cells")
            mesh = df.UnitCubeMesh(number_cells[0], number_cells[1],
                                   number_cells[2])
        elif meshtype == 'Box':
            x0 = libspud.get_option(
                "/geometry/mesh::Mesh/source::Box/lower_back_left")
            x1 = libspud.get_option(
                "/geometry/mesh::Mesh/source::Box/upper_front_right")
            number_cells = libspud.get_option(
                "/geometry/mesh::Mesh/source::Box/number_cells")
            mesh = df.BoxMesh(x0[0], x0[1], x0[2], x1[0], x1[1], x1[2],
                              number_cells[0], number_cells[1],
                              number_cells[2])
        elif meshtype == 'UnitInterval':
            number_cells = libspud.get_option(
                "/geometry/mesh::Mesh/source::UnitInterval/number_cells")
            mesh = df.UnitIntervalMesh(number_cells)
        elif meshtype == 'Interval':
            number_cells = libspud.get_option(
                "/geometry/mesh::Mesh/source::Interval/number_cells")
            left = libspud.get_option(
                "/geometry/mesh::Mesh/source::Interval/left")
            right = libspud.get_option(
                "/geometry/mesh::Mesh/source::Interval/right")
            mesh = df.IntervalMesh(number_cells, left, right)
        elif meshtype == 'File':
            mesh_filename = libspud.get_option(
                "/geometry/mesh::Mesh/source::File/file")
            print "tfml_file  = ", self.tfml_file, "mesh_filename=", mesh_filename
            mesh = df.Mesh(mesh_filename)
        else:
            df.error("Error: unknown mesh type " + meshtype)

        #set the functionspace for n-d solitary waves
        path = "/system::" + system_name + "/field::"
        p_family = libspud.get_option(path + p_name +
                                      "/type/rank/element/family")
        p_degree = libspud.get_option(path + p_name +
                                      "/type/rank/element/degree")
        f_family = libspud.get_option(path + f_name +
                                      "/type/rank/element/family")
        f_degree = libspud.get_option(path + f_name +
                                      "/type/rank/element/degree")
        pe = df.FiniteElement(p_family, mesh.ufl_cell(), p_degree)
        ve = df.FiniteElement(f_family, mesh.ufl_cell(), f_degree)
        e = pe * ve
        self.functionspace = df.FunctionSpace(mesh, e)

        #work out the order of the fields
        for i in xrange(
                libspud.option_count("/system::" + system_name + "/field")):
            name = libspud.get_option("/system::" + system_name + "/field[" +
                                      ` i ` + "]/name")
            if name == f_name:
                self.f_index = i
            if name == p_name:
                self.p_index = i
    def run(self):
        """ Perform the simulation! """

        # Time-stepping parameters and constants
        LOG.info("Setting up a few constants...")
        T = self.options["T"]
        t = self.options["t"]
        theta = self.options["theta"]
        dt = self.options["dt"]
        dimension = self.options["dimension"]
        g_magnitude = self.options["g_magnitude"]

        # Get the function spaces
        U = self.function_spaces["VelocityFunctionSpace"]
        H = self.function_spaces["FreeSurfaceFunctionSpace"]

        # Is the Velocity field represented by a discontinous function space?
        dg = (U.ufl_element().family() == "Discontinuous Lagrange")

        # Weight u and h by theta to obtain the theta time-stepping scheme.
        assert (theta >= 0.0 and theta <= 1.0)
        LOG.info("Time-stepping scheme using theta = %g" % (theta))
        u_mid = (1.0 - theta) * self.u0 + theta * self.u
        h_mid = (1.0 - theta) * self.h0 + theta * self.h

        # The total height of the free surface.
        self.h_total = self.h_mean + self.h0

        # Non-linear approximation to the velocity
        u_nl = Function(U).assign(self.u0)

        # Second-order Adams-Bashforth velocity
        u_bash = (3.0 / 2.0) * self.u0 - (1.0 / 2.0) * self.u00

        # Simple P1 function space, to be used in the stabilisation routines (if applicable).
        P1 = FunctionSpace(self.mesh, "CG", 1)
        cellsize = CellSize(self.mesh)

        ###########################################################
        ################# Tentative velocity step #################
        ###########################################################

        # The collection of all the individual terms in their weak form.
        LOG.info("Constructing form...")
        F = 0

        # Mass term
        if (self.options["have_momentum_mass"]):
            LOG.debug("Momentum equation: Adding mass term...")
            M_momentum = (1.0 / dt) * (inner(self.w, self.u) -
                                       inner(self.w, self.u0)) * dx
            F += M_momentum

        # Append any Expression objects for weak BCs here.
        weak_bc_expressions = []

        # Advection term
        if (self.options["have_momentum_advection"]):
            LOG.debug("Momentum equation: Adding advection term...")

            if (self.options["integrate_advection_term_by_parts"]):
                outflow = (dot(self.u0, self.n) +
                           abs(dot(self.u0, self.n))) / 2.0

                A_momentum = -inner(dot(u_nl, grad(self.w)),
                                    u_bash) * dx - inner(
                                        dot(u_bash, grad(u_nl)), self.w) * dx
                A_momentum += inner(self.w, outflow * u_mid) * ds
                if (dg):
                    # Only add interior facet integrals if we are dealing with a discontinous Galerkin discretisation.
                    A_momentum += dot(
                        outflow('+') * u_mid('+') - outflow('-') * u_mid('-'),
                        jump(self.w)) * dS

            else:
                A_momentum = inner(dot(grad(self.u), u_nl), self.w) * dx
            F += A_momentum

        # Viscous stress term. Note that the viscosity is kinematic (not dynamic).
        if (self.options["have_momentum_stress"]):
            LOG.debug("Momentum equation: Adding stress term...")

            viscosity = Function(H)

            # Background viscosity
            background_viscosity = Function(H).interpolate(
                Expression(
                    libspud.get_option(
                        "/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value/constant"
                    )))
            viscosity.assign(background_viscosity)

            # Eddy viscosity
            if (self.options["have_turbulence_parameterisation"]):
                LOG.debug(
                    "Momentum equation: Adding turbulence parameterisation...")
                base_option_path = "/system/equations/momentum_equation/turbulence_parameterisation"
                # Large eddy simulation (LES)
                if (libspud.have_option(base_option_path + "/les")):
                    les = LES(self.mesh, H)
                    density = Constant(
                        1.0
                    )  # We divide through by density in the momentum equation, so just set this to 1.0 for now.
                    smagorinsky_coefficient = Constant(
                        libspud.get_option(
                            base_option_path +
                            "/les/smagorinsky/smagorinsky_coefficient"))

                    eddy_viscosity = Function(H)
                    eddy_viscosity_lhs, eddy_viscosity_rhs = les.eddy_viscosity(
                        u_mid, density, smagorinsky_coefficient)
                    eddy_viscosity_problem = LinearVariationalProblem(
                        eddy_viscosity_lhs,
                        eddy_viscosity_rhs,
                        eddy_viscosity,
                        bcs=[])
                    eddy_viscosity_solver = LinearVariationalSolver(
                        eddy_viscosity_problem)

                # Add on eddy viscosity
                viscosity += eddy_viscosity

            # Stress tensor: tau = grad(u) + transpose(grad(u)) - (2/3)*div(u)
            if (not dg):
                # Perform a double dot product of the stress tensor and grad(w).
                K_momentum = -viscosity * inner(
                    grad(self.u) + grad(self.u).T, grad(self.w)) * dx
                #K_momentum += viscosity*(2.0/3.0)*inner(div(self.u)*Identity(dimension), grad(self.w))*dx
            else:
                # Interior penalty method
                cellsize = Constant(
                    0.2
                )  # In general, we should use CellSize(self.mesh) instead.
                alpha = 1 / cellsize  # Penalty parameter.

                K_momentum = -viscosity('+') * inner(grad(u_mid), grad(
                    self.w)) * dx
                for dim in range(self.options["dimension"]):
                    K_momentum += -viscosity('+') * (
                        alpha('+') / cellsize('+')) * dot(
                            jump(self.w[dim], self.n), jump(
                                u_mid[dim], self.n)) * dS
                    K_momentum += viscosity('+') * dot(
                        avg(grad(self.w[dim])), jump(u_mid[dim], self.n)
                    ) * dS + viscosity('+') * dot(jump(self.w[dim], self.n),
                                                  avg(grad(u_mid[dim]))) * dS

            F -= K_momentum  # Negative sign here because we are bringing the stress term over from the RHS.

        # The gradient of the height of the free surface, h
        LOG.debug("Momentum equation: Adding gradient term...")
        C_momentum = -g_magnitude * inner(self.w, grad(self.h0)) * dx
        F -= C_momentum

        # Quadratic drag term in the momentum equation
        if (self.options["have_drag"]):
            LOG.debug("Momentum equation: Adding drag term...")

            base_option_path = "/system/equations/momentum_equation/drag_term"

            # Get the bottom drag/friction coefficient.
            LOG.debug("Momentum equation: Adding bottom drag contribution...")
            bottom_drag = ExpressionFromOptions(
                path=base_option_path +
                "/scalar_field::BottomDragCoefficient/value",
                t=t).get_expression()
            bottom_drag = Function(H).interpolate(bottom_drag)

            # Add on the turbine drag, if provided.
            self.array = None

            # Magnitude of the velocity field
            magnitude = sqrt(dot(self.u0, self.u0))

            # Form the drag term
            array = sw.get_turbine_array()
            if (array):
                LOG.debug(
                    "Momentum equation: Adding turbine drag contribution...")
                drag_coefficient = bottom_drag + array.turbine_drag()
            else:
                drag_coefficient = bottom_drag
            D_momentum = -inner(
                self.w,
                (drag_coefficient * magnitude / self.h_total) * self.u) * dx
            F -= D_momentum

        # Add in any source terms
        if (self.options["have_momentum_source"]):
            LOG.debug("Momentum equation: Adding source term...")
            momentum_source_expression = ExpressionFromOptions(
                path=
                "/system/equations/momentum_equation/source_term/vector_field::Source/value",
                t=t).get_expression()
            momentum_source_function = Function(U)
            F -= inner(
                self.w,
                momentum_source_function.interpolate(
                    momentum_source_expression)) * dx

        # Add in any SU stabilisation
        if (self.options["have_su_stabilisation"]):
            LOG.debug(
                "Momentum equation: Adding streamline-upwind stabilisation term..."
            )
            stabilisation = Stabilisation(self.mesh, P1, cellsize)

            magnitude = magnitude_vector(self.u0, P1)

            # Bound the values for the magnitude below by 1.0e-9 for numerical stability reasons.
            u_nodes = magnitude.vector()
            near_zero = numpy.array([1.0e-9 for i in range(len(u_nodes))])
            u_nodes.set_local(numpy.maximum(u_nodes.array(), near_zero))

            diffusivity = ExpressionFromOptions(
                path=
                "/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value",
                t=self.options["t"]).get_expression()
            diffusivity = Function(H).interpolate(
                diffusivity)  # Background viscosity
            grid_pe = grid_peclet_number(diffusivity, magnitude, P1, cellsize)

            # Bound the values for grid_pe below by 1.0e-9 for numerical stability reasons.
            grid_pe_nodes = grid_pe.vector()
            values = numpy.array([1.0e-9 for i in range(len(grid_pe_nodes))])
            grid_pe_nodes.set_local(
                numpy.maximum(grid_pe_nodes.array(), values))

            F += stabilisation.streamline_upwind(self.w, self.u0, magnitude,
                                                 grid_pe)

        LOG.info("Form construction complete.")

        ##########################################################
        ################ Pressure correction step ################
        ##########################################################
        u_tent = Function(U)
        u_tent_nl = theta * u_tent + (1.0 - theta) * self.u0
        F_h_corr = inner(self.v, (self.h - self.h0))*dx \
                   + g_magnitude*(dt**2)*(theta**2)*self.h_total*inner(grad(self.v), grad(self.h - self.h0))*dx \
                   + dt*self.v*div(self.h_total*u_tent_nl)*dx

        ##########################################################
        ################ Velocity correction step ################
        ##########################################################
        h1 = Function(H)
        u1 = Function(U)
        F_u_corr = (1.0 / dt) * inner(
            self.w, self.u - u_tent) * dx + g_magnitude * theta * inner(
                self.w, grad(h1 - self.h0)) * dx

        LOG.info("Applying strong Dirichlet boundary conditions...")
        # Get all the Dirichlet boundary conditions for the Velocity field
        bcs_u = []
        bcs_u2 = []
        bcs_h = []
        bc_expressions = []
        for i in range(
                0,
                libspud.option_count(
                    "/system/core_fields/vector_field::Velocity/boundary_condition"
                )):
            if (libspud.have_option(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet"
                    % i
            ) and not libspud.have_option(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet/apply_weakly"
                    % i)):
                expr = ExpressionFromOptions(path=(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet"
                    % i),
                                             t=t).get_expression()
                # Surface IDs on the domain boundary
                surface_ids = libspud.get_option(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/surface_ids"
                    % i)
                method = ("geometric" if dg else "topological")
                bc = DirichletBC(U, expr, surface_ids, method=method)
                bcs_u.append(bc)
                bc_expressions.append(expr)
                LOG.debug(
                    "Applying Velocity BC #%d strongly to surface IDs: %s" %
                    (i, surface_ids))

        for i in range(
                0,
                libspud.option_count(
                    "/system/core_fields/vector_field::Velocity/boundary_condition"
                )):
            if (libspud.have_option(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet"
                    % i
            ) and not libspud.have_option(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet/apply_weakly"
                    % i)):
                expr = ExpressionFromOptions(path=(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet"
                    % i),
                                             t=t).get_expression()
                # Surface IDs on the domain boundary
                surface_ids = libspud.get_option(
                    "/system/core_fields/vector_field::Velocity/boundary_condition[%d]/surface_ids"
                    % i)
                method = ("geometric" if dg else "topological")
                bc = DirichletBC(U, expr, surface_ids, method=method)
                bcs_u2.append(bc)
                bc_expressions.append(expr)
                LOG.debug(
                    "Applying Velocity BC #%d strongly to surface IDs: %s" %
                    (i, surface_ids))

        for i in range(
                0,
                libspud.option_count(
                    "/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition/type::dirichlet"
                )):
            if (libspud.have_option(
                    "/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet"
                    % i
            ) and not (libspud.have_option(
                    "/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet/apply_weakly"
                    % i))):
                expr = ExpressionFromOptions(path=(
                    "/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet"
                    % i),
                                             t=t).get_expression()
                # Surface IDs on the domain boundary
                surface_ids = libspud.get_option(
                    "/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/surface_ids"
                    % i)
                method = ("geometric" if dg else "topological")
                bc = DirichletBC(H, expr, surface_ids, method=method)
                bcs_h.append(bc)
                bc_expressions.append(expr)
                LOG.debug(
                    "Applying FreeSurfacePerturbation BC #%d strongly to surface IDs: %s"
                    % (i, surface_ids))

        # Prepare solver_parameters dictionary
        LOG.debug("Defining solver_parameters dictionary...")
        solver_parameters = {
            'ksp_monitor': True,
            'ksp_view': False,
            'pc_view': False,
            'snes_type': 'ksponly',
            'ksp_max_it': 10000
        }  # NOTE: use 'snes_type': 'newtonls' for production runs.

        # KSP (iterative solver) options
        solver_parameters["ksp_type"] = libspud.get_option(
            "/system/solver/iterative_method/name")
        solver_parameters["ksp_rtol"] = libspud.get_option(
            "/system/solver/relative_error")

        solver_parameters['ksp_converged_reason'] = True
        solver_parameters['ksp_monitor_true_residual'] = True

        # Preconditioner options
        solver_parameters["pc_type"] = libspud.get_option(
            "/system/solver/preconditioner/name")
        # Fieldsplit sub-options
        if (solver_parameters["pc_type"] == "fieldsplit"):
            LOG.debug("Setting up the fieldsplit preconditioner...")
            solver_parameters["pc_fieldsplit_type"] = libspud.get_option(
                "/system/solver/preconditioner::fieldsplit/type/name")
            if (solver_parameters["pc_fieldsplit_type"] == "schur"):
                solver_parameters[
                    "pc_fieldsplit_schur_fact_type"] = libspud.get_option(
                        "/system/solver/preconditioner::fieldsplit/type::schur/fact_type/name"
                    )
            solver_parameters["fieldsplit_0_ksp_type"] = libspud.get_option(
                "/system/solver/preconditioner::fieldsplit/block_0_ksp_type/iterative_method/name"
            )
            solver_parameters["fieldsplit_1_ksp_type"] = libspud.get_option(
                "/system/solver/preconditioner::fieldsplit/block_1_ksp_type/iterative_method/name"
            )

            if (libspud.get_option(
                    "/system/solver/preconditioner::fieldsplit/block_0_pc_type/preconditioner/name"
            ) != "ilu"):
                solver_parameters["fieldsplit_0_pc_type"] = libspud.get_option(
                    "/system/solver/preconditioner::fieldsplit/block_0_pc_type/preconditioner/name"
                )
                solver_parameters["fieldsplit_1_pc_type"] = libspud.get_option(
                    "/system/solver/preconditioner::fieldsplit/block_1_pc_type/preconditioner/name"
                )

            # Enable inner iteration monitors.
            solver_parameters["fieldsplit_0_ksp_monitor"] = True
            solver_parameters["fieldsplit_1_ksp_monitor"] = True
            solver_parameters["fieldsplit_0_pc_factor_shift_type"] = 'INBLOCKS'
            solver_parameters["fieldsplit_1_pc_factor_shift_type"] = 'INBLOCKS'

        # Construct the solver objects
        problem_tent = LinearVariationalProblem(lhs(F),
                                                rhs(F),
                                                u_tent,
                                                bcs=bcs_u)
        solver_tent = LinearVariationalSolver(problem_tent,
                                              solver_parameters={
                                                  'ksp_monitor': False,
                                                  'ksp_view': False,
                                                  'pc_view': False,
                                                  'pc_type': 'sor',
                                                  'ksp_type': 'gmres',
                                                  'ksp_rtol': 1.0e-7
                                              })

        problem_h_corr = LinearVariationalProblem(lhs(F_h_corr),
                                                  rhs(F_h_corr),
                                                  h1,
                                                  bcs=bcs_h)
        solver_h_corr = LinearVariationalSolver(problem_h_corr,
                                                solver_parameters={
                                                    'ksp_monitor': False,
                                                    'ksp_view': False,
                                                    'pc_view': False,
                                                    'pc_type': 'sor',
                                                    'ksp_type': 'gmres',
                                                    'ksp_rtol': 1.0e-7
                                                })

        problem_u_corr = LinearVariationalProblem(lhs(F_u_corr),
                                                  rhs(F_u_corr),
                                                  u1,
                                                  bcs=bcs_u2)
        solver_u_corr = LinearVariationalSolver(problem_u_corr,
                                                solver_parameters={
                                                    'ksp_monitor': False,
                                                    'ksp_view': False,
                                                    'pc_view': False,
                                                    'pc_type': 'sor',
                                                    'ksp_type': 'gmres',
                                                    'ksp_rtol': 1.0e-7
                                                })

        t += dt
        iterations_since_dump = 1
        iterations_since_checkpoint = 1

        # PETSc solver run-times
        from petsc4py import PETSc
        main_solver_stage = PETSc.Log.Stage('Main block-coupled system solve')

        total_solver_time = 0.0
        # The time-stepping loop
        LOG.info("Entering the time-stepping loop...")
        EPSILON = 1.0e-14

        while t <= T + EPSILON:  # A small value EPSILON is added here in case of round-off error.
            LOG.info("t = %g" % t)

            while True:
                ## Update any time-dependent Functions and Expressions.

                # Re-compute the velocity magnitude and grid Peclet number fields.
                if (self.options["have_su_stabilisation"]):
                    magnitude.assign(magnitude_vector(self.u0, P1))

                    # Bound the values for the magnitude below by 1.0e-9 for numerical stability reasons.
                    u_nodes = magnitude.vector()
                    near_zero = numpy.array(
                        [1.0e-9 for i in range(len(u_nodes))])
                    u_nodes.set_local(numpy.maximum(u_nodes.array(),
                                                    near_zero))

                    grid_pe.assign(
                        grid_peclet_number(diffusivity, magnitude, P1,
                                           cellsize))

                    # Bound the values for grid_pe below by 1.0e-9 for numerical stability reasons.
                    grid_pe_nodes = grid_pe.vector()
                    values = numpy.array(
                        [1.0e-9 for i in range(len(grid_pe_nodes))])
                    grid_pe_nodes.set_local(
                        numpy.maximum(grid_pe_nodes.array(), values))

                if (self.options["have_turbulence_parameterisation"]):
                    eddy_viscosity_solver.solve()
                    viscosity.assign(background_viscosity + eddy_viscosity)

                # Time-dependent source terms
                if (self.options["have_momentum_source"]):
                    momentum_source_expression.t = t
                    momentum_source_function.interpolate(
                        momentum_source_expression)
                if (self.options["have_continuity_source"]):
                    continuity_source_expression.t = t
                    continuity_source_function.interpolate(
                        continuity_source_expression)

                # Update any time-varying DirichletBC objects.
                for expr in bc_expressions:
                    expr.t = t
                for expr in weak_bc_expressions:
                    expr.t = t

                # Solve the system of equations!
                start_solver_time = mpi4py.MPI.Wtime()
                main_solver_stage.push()
                LOG.debug("Solving the system of equations...")

                solver_tent.solve()
                solver_h_corr.solve()
                solver_u_corr.solve()

                main_solver_stage.pop()
                end_solver_time = mpi4py.MPI.Wtime()
                total_solver_time += (end_solver_time - start_solver_time)

                # Move to next time step
                if (steady_state(u1, u_nl, 1e-7)):
                    break
                u_nl.assign(u1)

            self.u00.assign(self.u0)
            self.u0.assign(u1)
            self.h0.assign(h1)
            t += dt
            iterations_since_dump += 1
            iterations_since_checkpoint += 1
            LOG.debug("Moving to next time level...")

            # Write the solution to file.
            if ((self.options["dump_period"] is not None) and
                (dt * iterations_since_dump >= self.options["dump_period"])):
                LOG.debug("Writing data to file...")
                self.output_functions["Velocity"].assign(u1)
                self.output_files["Velocity"] << self.output_functions[
                    "Velocity"]
                self.output_functions["FreeSurfacePerturbation"].assign(h1)
                self.output_files[
                    "FreeSurfacePerturbation"] << self.output_functions[
                        "FreeSurfacePerturbation"]
                iterations_since_dump = 0  # Reset the counter.

            # Print out the total power generated by turbines.
            if (self.options["have_drag"] and self.array is not None):
                LOG.info("Power = %.2f" % self.array.power(u1, density=1000))

            # Checkpointing
            if ((self.options["checkpoint_period"] is not None)
                    and (dt * iterations_since_checkpoint >=
                         self.options["checkpoint_period"])):
                LOG.debug("Writing checkpoint data to file...")
                self.solution.dat.save("checkpoint")
                iterations_since_checkpoint = 0  # Reset the counter.

            # Check whether a steady-state has been reached.
            if (steady_state(u1, self.u0,
                             self.options["steady_state_tolerance"])
                    and steady_state(h1, self.h0,
                                     self.options["steady_state_tolerance"])):
                LOG.info(
                    "Steady-state attained. Exiting the time-stepping loop...")
                break

            self.compute_diagnostics()

        LOG.info("Out of the time-stepping loop.")

        LOG.debug("Total solver time: %.2f" % (total_solver_time))

        return u1, h1
Example #20
0
def get_productions_and_injections(prod_file, geothermal, foldername, cwd):
    import csv
    nPhases = libspud.option_count('/material_phase')
    ##Get into the folder
    os.chdir(foldername)
    String_id = "-S"
    String_prod = "- Volume rate"

    #Replace spaces by commas to make it consistent
    opal_options.producer_ids.replace(' ', ',')
    opal_options.injector_ids.replace(' ', ',')
    #Create a list with the integers
    producer_list = [
        int(e) if e.isdigit() else e
        for e in opal_options.producer_ids.split(',')
    ]
    injector_list = [
        int(e) if e.isdigit() else e
        for e in opal_options.injector_ids.split(',')
    ]

    with open(prod_file, 'rb') as csvfile:
        datareader = csv.reader(csvfile, delimiter=',', quotechar='|')
        counter = -1  #To account for the header
        for row in datareader:
            try:
                counter += 1
            except:
                continue

    timeList = np.zeros(counter)
    prod = np.zeros((nPhases, counter))
    inject = np.zeros((nPhases, counter))
    prod_temp = np.zeros((nPhases, counter))
    inject_temp = np.zeros((nPhases, counter))
    counter = 0
    with open(prod_file, 'rb') as csvfile:
        datareader = csv.reader(csvfile, delimiter=',', quotechar='|')
        prod_cols = []
        inject_cols = []

        header = True
        previousT = 0.0
        for row in datareader:
            try:
                if header:
                    #Find the positions of interest of the producers
                    for ids in producer_list:
                        for i in range(len(row)):
                            if (String_id + str(ids) + String_prod) in row[i]:
                                prod_cols.append(i)
                    #Find the positions of interest of the injectors
                    for ids in injector_list:
                        for i in range(len(row)):
                            if (String_id + str(ids) + String_prod) in row[i]:
                                inject_cols.append(i)
                    header = False
                    continue

                phase_prod = 0
                phase_inject = 0
                timeList[counter] = float(row[0])
                # Calculate deltaT from absolute times
                deltaT = float(row[0]) - previousT
                previousT = float(row[0])

                for i in range(len(row)):
                    # Update production
                    for j in range(len(prod_cols)):
                        if i == prod_cols[j]:
                            if geothermal:
                                #For geothermal I need to do temperature * production * rho * Cp
                                #CURRENTLY NOT INCLUDED Cp nor RHO
                                #First temperature, so we can calculate the production in this time level
                                prod_temp[phase_prod, counter] = abs(
                                    float(row[i]) * deltaT *
                                    float(row[i + nPhases * 2]))
                            prod[phase_prod,
                                 counter] = abs(float(row[i]) * deltaT)
                            phase_prod += 1
                            if phase_prod == nPhases: phase_prod = 0

                    # Update Injection
                    for j in range(len(inject_cols)):
                        if i == inject_cols[j]:
                            if geothermal:
                                #For geothermal I need to do temperature * production * rho * Cp
                                #CURRENTLY NOT INCLUDED Cp nor RHO
                                #First temperature, so we can calculate the production in this time level
                                inject_temp[phase_inject, counter] = abs(
                                    float(row[i]) * deltaT *
                                    float(row[i + nPhases * 2]))

                            inject[phase_inject,
                                   counter] = abs(float(row[i]) * deltaT)
                            phase_inject += 1
                            if phase_inject == nPhases: phase_inject = 0
                counter += 1
            except:
                continue
    ##Return to original path
    os.chdir(cwd)
    return timeList, prod, inject, prod_temp, inject_temp
Example #21
0
    def fill(self, optionpath, system, index):
        """Fill a function class with data describing that function using libspud, the given optionpath and the system its based on."""
        self.name = libspud.get_option(optionpath + "/name")
        self.symbol = libspud.get_option(optionpath + "/ufl_symbol").split(
            os.linesep)[0]
        self.system = system
        self.index = index
        self.type = libspud.get_option(optionpath + "/type/name")

        self.rank = libspud.get_option(optionpath + "/type/rank/name")
        self.family = None
        self.degree = None
        self.functional = None
        if self.type != "Constant":
            self.family = libspud.get_option(optionpath +
                                             "/type/rank/element/family")
            self.degree = libspud.get_option(optionpath +
                                             "/type/rank/element/degree")

        self.size = None
        self.shape = None
        self.symmetry = None
        if self.rank == "Vector":
            if libspud.have_option(optionpath + "/type/rank/element/size"):
                self.size = libspud.get_option(optionpath +
                                               "/type/rank/element/size")
        elif self.rank == "Tensor":
            if libspud.have_option(optionpath + "/type/rank/element/shape"):
                self.shape = libspud.get_option(optionpath +
                                                "/type/rank/element/shape")
            if libspud.have_option(optionpath +
                                   "/type/rank/element/symmetric"):
                self.symmetry = True

        self.enrichment_family = None
        self.enrichment_degree = None
        if libspud.have_option(optionpath + "/type/rank/element/enrichment"):
            self.enrichment_family = libspud.get_option(
                optionpath + "/type/rank/element/enrichment/element/family")
            self.enrichment_degree = libspud.get_option(
                optionpath + "/type/rank/element/enrichment/element/degree")

        if libspud.have_option(optionpath +
                               "/type/rank/element/quadrature_rule"):
            self.quadrature_rule = libspud.get_option(
                optionpath + "/type/rank/element/quadrature_rule/name")

        # this should be restricted by the schema to Constant coefficients:
        if libspud.have_option(optionpath + "/type/rank/value/functional"):
            functional_optionpath = optionpath + "/type/rank/value/functional"
            functional = buckettools.spud.SpudFunctionalBucket()
            functional.fill(functional_optionpath, self.system, self)
            self.functional = functional

        self.cpp = []
        for k in range(
                libspud.option_count(optionpath +
                                     "/type/rank/initial_condition")):
            cpp_optionpath = optionpath + "/type/rank/initial_condition[" + ` k ` + "]"
            if libspud.have_option(cpp_optionpath + "/cpp"):
                cpp_name = libspud.get_option(cpp_optionpath + "/name")
                cppexpression = buckettools.spud.SpudCppExpressionBucket()
                # get all the information about this expression from the options dictionary
                cppexpression.fill(cpp_optionpath, cpp_name, self)
                # let the field know about this cpp expression
                self.cpp.append(cppexpression)
                # done with this expression
                del cppexpression

        for j in range(
                libspud.option_count(optionpath +
                                     "/type/rank/boundary_condition")):
            bc_optionpath = optionpath + "/type/rank/boundary_condition[" + ` j ` + "]"
            bc_name = libspud.get_option(bc_optionpath + "/name")
            for k in range(
                    libspud.option_count(bc_optionpath + "/sub_components")):
                bc_comp_optionpath = bc_optionpath + "/sub_components[" + ` k ` + "]"
                bc_comp_name = libspud.get_option(bc_comp_optionpath + "/name")

                cpp_optionpath = bc_comp_optionpath + "/type"
                if libspud.have_option(cpp_optionpath + "/cpp"):
                    cpp_name = bc_name + bc_comp_name

                    cppexpression = buckettools.spud.SpudCppExpressionBucket()
                    # get all the information about this expression from the options dictionary
                    cppexpression.fill(cpp_optionpath, cpp_name, self)
                    # let the field know about this cpp expression
                    self.cpp.append(cppexpression)
                    # done with this expression
                    del cppexpression

        for k in range(libspud.option_count(optionpath + "/type/rank/value")):
            cpp_optionpath = optionpath + "/type/rank/value[" + ` k ` + "]"
            if libspud.have_option(cpp_optionpath + "/cpp"):
                cpp_name = libspud.get_option(cpp_optionpath + "/name")
                cppexpression = buckettools.spud.SpudCppExpressionBucket()
                # get all the information about this expression from the options dictionary
                cppexpression.fill(cpp_optionpath, cpp_name, self)
                # let the field know about this cpp expression
                self.cpp.append(cppexpression)
                # done with this expression
                del cppexpression
   def run(self):
      """ Perform the simulation! """

      # Time-stepping parameters and constants
      LOG.info("Setting up a few constants...")
      T = self.options["T"]
      t = self.options["t"]
      theta = self.options["theta"]
      dt = self.options["dt"]
      dimension = self.options["dimension"]
      g_magnitude = self.options["g_magnitude"]

      # Get the function spaces
      U = self.function_spaces["VelocityFunctionSpace"]
      H = self.function_spaces["FreeSurfaceFunctionSpace"]
      
      # Is the Velocity field represented by a discontinous function space?
      dg = (U.ufl_element().family() == "Discontinuous Lagrange")
      
      # Weight u and h by theta to obtain the theta time-stepping scheme.
      assert(theta >= 0.0 and theta <= 1.0)
      LOG.info("Time-stepping scheme using theta = %g" % (theta))
      u_mid = (1.0 - theta) * self.u0 + theta * self.u
      h_mid = (1.0 - theta) * self.h0 + theta * self.h
         
      # The total height of the free surface.
      self.h_total = self.h_mean + self.h0

      # Non-linear approximation to the velocity
      u_nl = Function(U).assign(self.u0)
      
      # Second-order Adams-Bashforth velocity
      u_bash = (3.0/2.0)*self.u0 - (1.0/2.0)*self.u00
      
      # Simple P1 function space, to be used in the stabilisation routines (if applicable).
      P1 = FunctionSpace(self.mesh, "CG", 1)
      cellsize = CellSize(self.mesh)

      ###########################################################
      ################# Tentative velocity step #################
      ###########################################################
      
      # The collection of all the individual terms in their weak form.
      LOG.info("Constructing form...")
      F = 0

      # Mass term
      if(self.options["have_momentum_mass"]):
         LOG.debug("Momentum equation: Adding mass term...")
         M_momentum = (1.0/dt)*(inner(self.w, self.u) - inner(self.w, self.u0))*dx
         F += M_momentum
         
      # Append any Expression objects for weak BCs here.
      weak_bc_expressions = []
      
      # Advection term
      if(self.options["have_momentum_advection"]):
         LOG.debug("Momentum equation: Adding advection term...")

         if(self.options["integrate_advection_term_by_parts"]):
            outflow = (dot(self.u0, self.n) + abs(dot(self.u0, self.n)))/2.0

            A_momentum = -inner(dot(u_nl, grad(self.w)), u_bash)*dx - inner(dot(u_bash, grad(u_nl)), self.w)*dx
            A_momentum += inner(self.w, outflow*u_mid)*ds
            if(dg):
               # Only add interior facet integrals if we are dealing with a discontinous Galerkin discretisation.
               A_momentum += dot(outflow('+')*u_mid('+') - outflow('-')*u_mid('-'), jump(self.w))*dS

         else:
            A_momentum = inner(dot(grad(self.u), u_nl), self.w)*dx
         F += A_momentum

      # Viscous stress term. Note that the viscosity is kinematic (not dynamic).
      if(self.options["have_momentum_stress"]):
         LOG.debug("Momentum equation: Adding stress term...")
         
         viscosity = Function(H)
         
         # Background viscosity
         background_viscosity = Function(H).interpolate(Expression(libspud.get_option("/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value/constant")))
         viscosity.assign(background_viscosity)

         # Eddy viscosity
         if(self.options["have_turbulence_parameterisation"]):
            LOG.debug("Momentum equation: Adding turbulence parameterisation...")
            base_option_path = "/system/equations/momentum_equation/turbulence_parameterisation"
            # Large eddy simulation (LES)
            if(libspud.have_option(base_option_path + "/les")):
               les = LES(self.mesh, H)
               density = Constant(1.0) # We divide through by density in the momentum equation, so just set this to 1.0 for now.
               smagorinsky_coefficient = Constant(libspud.get_option(base_option_path + "/les/smagorinsky/smagorinsky_coefficient"))
               
               eddy_viscosity = Function(H)
               eddy_viscosity_lhs, eddy_viscosity_rhs = les.eddy_viscosity(u_mid, density, smagorinsky_coefficient)
               eddy_viscosity_problem = LinearVariationalProblem(eddy_viscosity_lhs, eddy_viscosity_rhs, eddy_viscosity, bcs=[])
               eddy_viscosity_solver = LinearVariationalSolver(eddy_viscosity_problem)
               
            # Add on eddy viscosity
            viscosity += eddy_viscosity

         # Stress tensor: tau = grad(u) + transpose(grad(u)) - (2/3)*div(u)
         if(not dg):
            # Perform a double dot product of the stress tensor and grad(w).
            K_momentum = -viscosity*inner(grad(self.u) + grad(self.u).T, grad(self.w))*dx
            #K_momentum += viscosity*(2.0/3.0)*inner(div(self.u)*Identity(dimension), grad(self.w))*dx
         else:
            # Interior penalty method
            cellsize = Constant(0.2) # In general, we should use CellSize(self.mesh) instead.
            alpha = 1/cellsize # Penalty parameter.
            
            K_momentum = -viscosity('+')*inner(grad(u_mid), grad(self.w))*dx
            for dim in range(self.options["dimension"]):
               K_momentum += -viscosity('+')*(alpha('+')/cellsize('+'))*dot(jump(self.w[dim], self.n), jump(u_mid[dim], self.n))*dS
               K_momentum += viscosity('+')*dot(avg(grad(self.w[dim])), jump(u_mid[dim], self.n))*dS + viscosity('+')*dot(jump(self.w[dim], self.n), avg(grad(u_mid[dim])))*dS

         F -= K_momentum # Negative sign here because we are bringing the stress term over from the RHS.

      # The gradient of the height of the free surface, h
      LOG.debug("Momentum equation: Adding gradient term...")
      C_momentum = -g_magnitude*inner(self.w, grad(self.h0))*dx
      F -= C_momentum

      # Quadratic drag term in the momentum equation
      if(self.options["have_drag"]):
         LOG.debug("Momentum equation: Adding drag term...")
         
         base_option_path = "/system/equations/momentum_equation/drag_term"
         
         # Get the bottom drag/friction coefficient.
         LOG.debug("Momentum equation: Adding bottom drag contribution...")
         bottom_drag = ExpressionFromOptions(path=base_option_path+"/scalar_field::BottomDragCoefficient/value", t=t).get_expression()
         bottom_drag = Function(H).interpolate(bottom_drag)
         
         # Add on the turbine drag, if provided.
         self.array = None
         
         # Magnitude of the velocity field
         magnitude = sqrt(dot(self.u0, self.u0))
         
         # Form the drag term
         array = sw.get_turbine_array()
         if(array):
            LOG.debug("Momentum equation: Adding turbine drag contribution...")
            drag_coefficient = bottom_drag + array.turbine_drag()
         else:
            drag_coefficient = bottom_drag
         D_momentum = -inner(self.w, (drag_coefficient*magnitude/self.h_total)*self.u)*dx
         F -= D_momentum

      # Add in any source terms
      if(self.options["have_momentum_source"]):
         LOG.debug("Momentum equation: Adding source term...")
         momentum_source_expression = ExpressionFromOptions(path = "/system/equations/momentum_equation/source_term/vector_field::Source/value", t=t).get_expression()
         momentum_source_function = Function(U)
         F -= inner(self.w, momentum_source_function.interpolate(momentum_source_expression))*dx
         
      # Add in any SU stabilisation
      if(self.options["have_su_stabilisation"]):
         LOG.debug("Momentum equation: Adding streamline-upwind stabilisation term...")
         stabilisation = Stabilisation(self.mesh, P1, cellsize)
         
         magnitude = magnitude_vector(self.u0, P1)

         # Bound the values for the magnitude below by 1.0e-9 for numerical stability reasons.
         u_nodes = magnitude.vector()
         near_zero = numpy.array([1.0e-9 for i in range(len(u_nodes))])
         u_nodes.set_local(numpy.maximum(u_nodes.array(), near_zero))

         diffusivity = ExpressionFromOptions(path = "/system/equations/momentum_equation/stress_term/scalar_field::Viscosity/value", t=self.options["t"]).get_expression()
         diffusivity = Function(H).interpolate(diffusivity) # Background viscosity
         grid_pe = grid_peclet_number(diffusivity, magnitude, P1, cellsize)
   
         # Bound the values for grid_pe below by 1.0e-9 for numerical stability reasons. 
         grid_pe_nodes = grid_pe.vector()
         values = numpy.array([1.0e-9 for i in range(len(grid_pe_nodes))])
         grid_pe_nodes.set_local(numpy.maximum(grid_pe_nodes.array(), values))

         F += stabilisation.streamline_upwind(self.w, self.u0, magnitude, grid_pe)

      LOG.info("Form construction complete.")

      ##########################################################
      ################ Pressure correction step ################
      ##########################################################   
      u_tent = Function(U)
      u_tent_nl = theta*u_tent + (1.0-theta)*self.u0
      F_h_corr = inner(self.v, (self.h - self.h0))*dx \
                 + g_magnitude*(dt**2)*(theta**2)*self.h_total*inner(grad(self.v), grad(self.h - self.h0))*dx \
                 + dt*self.v*div(self.h_total*u_tent_nl)*dx
                 
      ##########################################################
      ################ Velocity correction step ################
      ##########################################################   
      h1 = Function(H)
      u1 = Function(U)
      F_u_corr = (1.0/dt)*inner(self.w, self.u - u_tent)*dx + g_magnitude*theta*inner(self.w, grad(h1 - self.h0))*dx
                 
      LOG.info("Applying strong Dirichlet boundary conditions...")
      # Get all the Dirichlet boundary conditions for the Velocity field
      bcs_u = []; bcs_u2 = []
      bcs_h = []
      bc_expressions = []
      for i in range(0, libspud.option_count("/system/core_fields/vector_field::Velocity/boundary_condition")):
         if(libspud.have_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet" % i) and
            not libspud.have_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet/apply_weakly" % i)):
            expr = ExpressionFromOptions(path = ("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet" % i), t=t).get_expression()
            # Surface IDs on the domain boundary
            surface_ids = libspud.get_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/surface_ids" % i)
            method = ("geometric" if dg else "topological")
            bc = DirichletBC(U, expr, surface_ids, method=method)
            bcs_u.append(bc)
            bc_expressions.append(expr)
            LOG.debug("Applying Velocity BC #%d strongly to surface IDs: %s" % (i, surface_ids))

      for i in range(0, libspud.option_count("/system/core_fields/vector_field::Velocity/boundary_condition")):
         if(libspud.have_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet" % i) and
            not libspud.have_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet/apply_weakly" % i)):
            expr = ExpressionFromOptions(path = ("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/type::dirichlet" % i), t=t).get_expression()
            # Surface IDs on the domain boundary
            surface_ids = libspud.get_option("/system/core_fields/vector_field::Velocity/boundary_condition[%d]/surface_ids" % i)
            method = ("geometric" if dg else "topological")
            bc = DirichletBC(U, expr, surface_ids, method=method)
            bcs_u2.append(bc)
            bc_expressions.append(expr)
            LOG.debug("Applying Velocity BC #%d strongly to surface IDs: %s" % (i, surface_ids))


      for i in range(0, libspud.option_count("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition/type::dirichlet")):
         if(libspud.have_option("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet" % i) and
            not(libspud.have_option("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet/apply_weakly" % i))):
            expr = ExpressionFromOptions(path = ("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/type::dirichlet" % i), t=t).get_expression()
            # Surface IDs on the domain boundary
            surface_ids = libspud.get_option("/system/core_fields/scalar_field::FreeSurfacePerturbation/boundary_condition[%d]/surface_ids" % i)
            method = ("geometric" if dg else "topological")
            bc = DirichletBC(H, expr, surface_ids, method=method)
            bcs_h.append(bc)
            bc_expressions.append(expr)
            LOG.debug("Applying FreeSurfacePerturbation BC #%d strongly to surface IDs: %s" % (i, surface_ids))
            
      # Prepare solver_parameters dictionary
      LOG.debug("Defining solver_parameters dictionary...")
      solver_parameters = {'ksp_monitor': True, 'ksp_view': False, 'pc_view': False, 'snes_type': 'ksponly', 'ksp_max_it':10000} # NOTE: use 'snes_type': 'newtonls' for production runs.
      
      # KSP (iterative solver) options
      solver_parameters["ksp_type"] = libspud.get_option("/system/solver/iterative_method/name")
      solver_parameters["ksp_rtol"] = libspud.get_option("/system/solver/relative_error")
      
      solver_parameters['ksp_converged_reason'] = True
      solver_parameters['ksp_monitor_true_residual'] = True
      
      # Preconditioner options
      solver_parameters["pc_type"] = libspud.get_option("/system/solver/preconditioner/name")
      # Fieldsplit sub-options
      if(solver_parameters["pc_type"] == "fieldsplit"):
         LOG.debug("Setting up the fieldsplit preconditioner...")
         solver_parameters["pc_fieldsplit_type"] = libspud.get_option("/system/solver/preconditioner::fieldsplit/type/name")
         if(solver_parameters["pc_fieldsplit_type"] == "schur"):
            solver_parameters["pc_fieldsplit_schur_fact_type"] = libspud.get_option("/system/solver/preconditioner::fieldsplit/type::schur/fact_type/name")
         solver_parameters["fieldsplit_0_ksp_type"] = libspud.get_option("/system/solver/preconditioner::fieldsplit/block_0_ksp_type/iterative_method/name")
         solver_parameters["fieldsplit_1_ksp_type"] = libspud.get_option("/system/solver/preconditioner::fieldsplit/block_1_ksp_type/iterative_method/name")

         if(libspud.get_option("/system/solver/preconditioner::fieldsplit/block_0_pc_type/preconditioner/name") != "ilu"):
            solver_parameters["fieldsplit_0_pc_type"] = libspud.get_option("/system/solver/preconditioner::fieldsplit/block_0_pc_type/preconditioner/name")
            solver_parameters["fieldsplit_1_pc_type"] = libspud.get_option("/system/solver/preconditioner::fieldsplit/block_1_pc_type/preconditioner/name")
            
         # Enable inner iteration monitors.
         solver_parameters["fieldsplit_0_ksp_monitor"] = True
         solver_parameters["fieldsplit_1_ksp_monitor"] = True
         solver_parameters["fieldsplit_0_pc_factor_shift_type"] = 'INBLOCKS'
         solver_parameters["fieldsplit_1_pc_factor_shift_type"] = 'INBLOCKS'
         
      # Construct the solver objects
      problem_tent = LinearVariationalProblem(lhs(F), rhs(F), u_tent, bcs=bcs_u)
      solver_tent = LinearVariationalSolver(problem_tent, solver_parameters={'ksp_monitor': False, 
                                                                              'ksp_view': False, 
                                                                              'pc_view': False, 
                                                                              'pc_type': 'sor',
                                                                              'ksp_type': 'gmres',
                                                                              'ksp_rtol': 1.0e-7})

      problem_h_corr = LinearVariationalProblem(lhs(F_h_corr), rhs(F_h_corr), h1, bcs=bcs_h)
      solver_h_corr = LinearVariationalSolver(problem_h_corr, solver_parameters={'ksp_monitor': False, 
                                                                                 'ksp_view': False, 
                                                                                 'pc_view': False, 
                                                                                 'pc_type': 'sor',
                                                                                 'ksp_type': 'gmres',
                                                                                 'ksp_rtol': 1.0e-7})
      
     
      problem_u_corr = LinearVariationalProblem(lhs(F_u_corr), rhs(F_u_corr), u1, bcs=bcs_u2)
      solver_u_corr = LinearVariationalSolver(problem_u_corr, solver_parameters={'ksp_monitor': False, 
                                                                                 'ksp_view': False, 
                                                                                 'pc_view': False, 
                                                                                 'pc_type': 'sor',
                                                                                 'ksp_type': 'gmres',
                                                                                 'ksp_rtol': 1.0e-7})
      
      
      t += dt
      iterations_since_dump = 1
      iterations_since_checkpoint = 1
      
      # PETSc solver run-times
      from petsc4py import PETSc
      main_solver_stage = PETSc.Log.Stage('Main block-coupled system solve')

      total_solver_time = 0.0
      # The time-stepping loop
      LOG.info("Entering the time-stepping loop...")
      EPSILON = 1.0e-14
      
      while t <= T + EPSILON: # A small value EPSILON is added here in case of round-off error.
         LOG.info("t = %g" % t)

         while True:
            ## Update any time-dependent Functions and Expressions.
            
            # Re-compute the velocity magnitude and grid Peclet number fields.
            if(self.options["have_su_stabilisation"]):
               magnitude.assign(magnitude_vector(self.u0, P1))

               # Bound the values for the magnitude below by 1.0e-9 for numerical stability reasons.
               u_nodes = magnitude.vector()
               near_zero = numpy.array([1.0e-9 for i in range(len(u_nodes))])
               u_nodes.set_local(numpy.maximum(u_nodes.array(), near_zero))
               
               grid_pe.assign(grid_peclet_number(diffusivity, magnitude, P1, cellsize))
         
               # Bound the values for grid_pe below by 1.0e-9 for numerical stability reasons. 
               grid_pe_nodes = grid_pe.vector()
               values = numpy.array([1.0e-9 for i in range(len(grid_pe_nodes))])
               grid_pe_nodes.set_local(numpy.maximum(grid_pe_nodes.array(), values))

            if(self.options["have_turbulence_parameterisation"]):
               eddy_viscosity_solver.solve()
               viscosity.assign(background_viscosity + eddy_viscosity)

            # Time-dependent source terms
            if(self.options["have_momentum_source"]):
               momentum_source_expression.t = t
               momentum_source_function.interpolate(momentum_source_expression)
            if(self.options["have_continuity_source"]):
               continuity_source_expression.t = t
               continuity_source_function.interpolate(continuity_source_expression)
               
            # Update any time-varying DirichletBC objects.
            for expr in bc_expressions:
               expr.t = t
            for expr in weak_bc_expressions:
               expr.t = t
                      
            # Solve the system of equations!
            start_solver_time = mpi4py.MPI.Wtime()
            main_solver_stage.push()
            LOG.debug("Solving the system of equations...")
            
            solver_tent.solve()
            solver_h_corr.solve()
            solver_u_corr.solve()
            
            main_solver_stage.pop()
            end_solver_time = mpi4py.MPI.Wtime()
            total_solver_time += (end_solver_time - start_solver_time)

            # Move to next time step  
            if(steady_state(u1, u_nl, 1e-7)):
               break
            u_nl.assign(u1)

         self.u00.assign(self.u0)
         self.u0.assign(u1)
         self.h0.assign(h1)
         t += dt
         iterations_since_dump += 1
         iterations_since_checkpoint += 1
         LOG.debug("Moving to next time level...")

         # Write the solution to file.
         if((self.options["dump_period"] is not None) and (dt*iterations_since_dump >= self.options["dump_period"])):
            LOG.debug("Writing data to file...")
            self.output_functions["Velocity"].assign(u1)
            self.output_files["Velocity"] << self.output_functions["Velocity"]
            self.output_functions["FreeSurfacePerturbation"].assign(h1)
            self.output_files["FreeSurfacePerturbation"] << self.output_functions["FreeSurfacePerturbation"]
            iterations_since_dump = 0 # Reset the counter.

         # Print out the total power generated by turbines.
         if(self.options["have_drag"] and self.array is not None):
            LOG.info("Power = %.2f" % self.array.power(u1, density=1000))
            
         # Checkpointing
         if((self.options["checkpoint_period"] is not None) and (dt*iterations_since_checkpoint >= self.options["checkpoint_period"])):
            LOG.debug("Writing checkpoint data to file...")
            self.solution.dat.save("checkpoint")
            iterations_since_checkpoint = 0 # Reset the counter.
            
         # Check whether a steady-state has been reached.
         if(steady_state(u1, self.u0, self.options["steady_state_tolerance"]) and steady_state(h1, self.h0, self.options["steady_state_tolerance"])):
            LOG.info("Steady-state attained. Exiting the time-stepping loop...")
            break

         self.compute_diagnostics()            


      LOG.info("Out of the time-stepping loop.")

      LOG.debug("Total solver time: %.2f" % (total_solver_time))

      return u1, h1
Example #23
0
def post_init(model, xml_path):

    model.start_time = get_optional('time_options/start_time', default=0.0)
    if libspud.have_option('time_options/adaptive_timestep'):
        option_path = 'time_options/adaptive_timestep/'
        model.adapt_timestep = True
        model.adapt_cfl = project(Constant(
            libspud.get_option(option_path + 'cfl_criteria')),
                                  model.R,
                                  name='cfl')
    else:
        model.adapt_timestep = False
        model.adapt_cfl = project(Constant(0.2), model.R, name='cfl')

    # ts info options
    if libspud.have_option('output_options/ts_info'):
        model.ts_info = True
    else:
        model.ts_info = False

    # plotting options
    option_path = 'output_options/plotting/'
    if libspud.have_option('output_options/plotting'):
        model.plot = libspud.get_option(option_path + 'plotting_interval')
        if libspud.have_option(option_path + 'output::both'):
            model.show_plot = True
            model.save_plot = True
        elif libspud.have_option(option_path + 'output::live_plotting'):
            model.show_plot = True
            model.save_plot = False
        elif libspud.have_option(option_path + 'output::save_plots'):
            model.show_plot = False
            model.save_plot = True
        else:
            raise Exception('unrecognised plotting output in options file')
        option_path = option_path + 'dimensionalise_plots/'
    else:
        model.plot = None

    # dimenionalisation
    model.g = project(Constant(
        get_optional(option_path + 'g_prime', default=1.0)),
                      model.R,
                      name='g_prime')
    model.h_0 = project(Constant(get_optional(option_path + 'h_0',
                                              default=1.0)),
                        model.R,
                        name='h_0')
    model.phi_0 = project(Constant(
        get_optional(option_path + 'phi_0', default=1.0)),
                          model.R,
                          name='phi_0')

    # non dimensional numbers
    option_path = 'non_dimensional_numbers/'
    model.Fr = project(Constant(get_optional(option_path + 'Fr',
                                             default=1.19)),
                       model.R,
                       name="Fr")
    model.beta = project(Constant(
        get_optional(option_path + 'beta', default=5e-3)),
                         model.R,
                         name="beta")

    # initial conditions
    model.form_ic = (
        {
            'id': 'momentum',
            'function': Function(model.V, name='ic_q'),
            'test_function': TestFunction(model.V)
        },
        {
            'id': 'height',
            'function': Function(model.V, name='ic_h'),
            'test_function': TestFunction(model.V)
        },
        {
            'id': 'volume_fraction',
            'function': Function(model.V, name='ic_phi'),
            'test_function': TestFunction(model.V)
        },
        {
            'id': 'deposit_depth',
            'function': Function(model.V, name='ic_phi_d'),
            'test_function': TestFunction(model.V)
        },
        {
            'id': 'initial_length',
            'function': Function(model.R, name='ic_X_n'),
            'test_function': TestFunction(model.R)
        },
        {
            'id': 'front_velocity',
            'function': Function(model.R, name='ic_u_N'),
            'test_function': TestFunction(model.R)
        },
        {
            'id': 'timestep',
            'function': Function(model.R, name='ic_k'),
            'test_function': TestFunction(model.R)
        },
        {
            'id': 'phi_int',
            'function': Function(model.R, name='ic_phi_int'),
            'test_function': TestFunction(model.R)
        },
    )

    option_path = 'initial_conditions/'
    var_paths = 'momentum', 'height', 'volume_fraction', 'deposit_depth', \
        'initial_length', 'front_velocity', 'timestep'

    # form defines ic
    for i, var_path in enumerate(var_paths):
        path = option_path + var_path + '/form'
        if libspud.have_option(path):
            if libspud.have_option(path + '/additional_form_var'):
                for j in range(
                        libspud.option_count(path +
                                             '/additional_form_var/var')):
                    py_code = libspud.get_option(
                        path + '/additional_form_var/var[%d]' % j)
                    exec py_code
            py_code = "model.form_ic[%d]['form'] = %s" % (
                i, libspud.get_option(path))
            exec py_code

    # expression defined ic
    model.w_ic_var = ''
    if (libspud.have_option(option_path + 'variables')
            and libspud.option_count(option_path + 'variables/var') > 0):
        n_var = libspud.option_count(option_path + 'variables/var')
        for i_var in range(n_var):
            name = libspud.get_child_name(option_path + 'variables/', i_var)
            var = name.split(':')[-1]
            code = libspud.get_option('initial_conditions/variables/' + name +
                                      '/code')
            model.w_ic_var = model.w_ic_var + var + ' = ' + code + ', '
    ic_exp = (read_ic(option_path + 'momentum', default='0.0'),
              read_ic(option_path + 'height', default='1.0'),
              read_ic(option_path + 'volume_fraction', default='1.0'),
              read_ic(option_path + 'deposit_depth', default='0.0'),
              read_ic(option_path + 'initial_length', default='1.0'),
              read_ic(option_path + 'front_velocity', default='1.19'),
              read_ic(option_path + 'timestep', default='1.0'), '0.0')
    exp_str = ('model.w_ic_e = Expression(ic_exp, model.W.ufl_element(), %s)' %
               model.w_ic_var)
    exec exp_str in globals(), locals()
Example #24
0
    def __init__(self, tfml_file,system_name='magma',p_name='Pressure',f_name='Porosity',c_name='c',n_name='n',m_name='m',d_name='d',N_name='N',h_squared_name='h_squared',x0_name='x0'):
        """read the tfml_file and use libspud to populate the internal parameters

        c: wavespeed
        n: permeability exponent
        m: bulk viscosity exponent
        d: wave dimension
        N: number of collocation points
        x0: coordinate wave peak
        h_squared:  the size of the system in compaction lengths
                    squared (h/delta)**2
        """
        # initialize libspud and extract parameters
        libspud.clear_options()
        libspud.load_options(tfml_file)
        # get model dimension
        self.dim = libspud.get_option("/geometry/dimension")
        self.system_name = system_name
        # get solitary wave parameters
        path="/system::"+system_name+"/coefficient::"
        scalar_value="/type::Constant/rank::Scalar/value::WholeMesh/constant"
        vector_value="/type::Constant/rank::Vector/value::WholeMesh/constant::dim"
        c = libspud.get_option(path+c_name+scalar_value)
        n = int(libspud.get_option(path+n_name+scalar_value))
        m = int(libspud.get_option(path+m_name+scalar_value))
        d = float(libspud.get_option(path+d_name+scalar_value))
        N = int(libspud.get_option(path+N_name+scalar_value))
        self.h = np.sqrt(libspud.get_option(path+h_squared_name+scalar_value))
        self.x0 = np.array(libspud.get_option(path+x0_name+vector_value))
        self.swave = SolitaryWave(c,n,m,d,N)
        self.rmax = self.swave.r[-1]
        self.tfml_file = tfml_file
  
        # check that d <= dim
        assert (d <= self.dim)   
        
        # sort out appropriate index for calculating distance r
        if d == 1:
            self.index = [self.dim - 1]
        else: 
            self.index = range(0,int(d))  
            
        # check that the origin point is the correct dimension
        assert (len(self.x0) == self.dim)
        
        
        #read in information for constructing Function space and dolfin objects
        # get the mesh parameters and reconstruct the mesh
        meshtype = libspud.get_option("/geometry/mesh/source[0]/name")
        if meshtype == 'UnitSquare':
            number_cells = libspud.get_option("/geometry/mesh[0]/source[0]/number_cells")
            diagonal = libspud.get_option("/geometry/mesh[0]/source[0]/diagonal")
            mesh = df.UnitSquareMesh(number_cells[0],number_cells[1],diagonal)
        elif meshtype == 'Rectangle':
            x0 = libspud.get_option("/geometry/mesh::Mesh/source::Rectangle/lower_left")
            x1 = libspud.get_option("/geometry/mesh::Mesh/source::Rectangle/upper_right")
            number_cells = libspud.get_option("/geometry/mesh::Mesh/source::Rectangle/number_cells")
            diagonal = libspud.get_option("/geometry/mesh[0]/source[0]/diagonal")
            mesh = df.RectangleMesh(x0[0],x0[1],x1[0],x1[1],number_cells[0],number_cells[1],diagonal)
        elif meshtype == 'UnitCube':
            number_cells = libspud.get_option("/geometry/mesh[0]/source[0]/number_cells")
            mesh = df.UnitCubeMesh(number_cells[0],number_cells[1],number_cells[2])
        elif meshtype == 'Box':
            x0 = libspud.get_option("/geometry/mesh::Mesh/source::Box/lower_back_left")
            x1 = libspud.get_option("/geometry/mesh::Mesh/source::Box/upper_front_right")
            number_cells = libspud.get_option("/geometry/mesh::Mesh/source::Box/number_cells")
            mesh = df.BoxMesh(x0[0],x0[1],x0[2],x1[0],x1[1],x1[2],number_cells[0],number_cells[1],number_cells[2])
        elif meshtype == 'UnitInterval':
            number_cells = libspud.get_option("/geometry/mesh::Mesh/source::UnitInterval/number_cells")
            mesh = df.UnitIntervalMesh(number_cells)
        elif meshtype == 'Interval':
            number_cells = libspud.get_option("/geometry/mesh::Mesh/source::Interval/number_cells")
            left = libspud.get_option("/geometry/mesh::Mesh/source::Interval/left")
            right = libspud.get_option("/geometry/mesh::Mesh/source::Interval/right")
            mesh = df.IntervalMesh(number_cells,left,right)
        elif meshtype == 'File':
            mesh_filename = libspud.get_option("/geometry/mesh::Mesh/source::File/file")
            print "tfml_file  = ",self.tfml_file, "mesh_filename=",mesh_filename
            mesh = df.Mesh(mesh_filename)
        else:
            df.error("Error: unknown mesh type "+meshtype)
           
        #set the functionspace for n-d solitary waves
        path="/system::"+system_name+"/field::"
        p_family = libspud.get_option(path+p_name+"/type/rank/element/family")
        p_degree = libspud.get_option(path+p_name+"/type/rank/element/degree")
        f_family = libspud.get_option(path+f_name+"/type/rank/element/family")
        f_degree = libspud.get_option(path+f_name+"/type/rank/element/degree")        
        pe = df.FiniteElement(p_family, mesh.ufl_cell(), p_degree)
        ve = df.FiniteElement(f_family, mesh.ufl_cell(), f_degree)
        e = pe*ve
        self.functionspace = df.FunctionSpace(mesh, e)

        #work out the order of the fields
        for i in xrange(libspud.option_count("/system::"+system_name+"/field")):
          name = libspud.get_option("/system::"+system_name+"/field["+`i`+"]/name")
          if name == f_name:
            self.f_index = i
          if name == p_name:
            self.p_index = i
Example #25
0
  def fill(self, optionpath, system, index):
    """Fill a function class with data describing that function using libspud, the given optionpath and the system its based on."""
    self.name       = libspud.get_option(optionpath+"/name")
    self.symbol     = libspud.get_option(optionpath+"/ufl_symbol").split("\n")[0]
    self.system     = system
    self.index      = index
    self.type       = libspud.get_option(optionpath+"/type/name")

    self.rank   = libspud.get_option(optionpath+"/type/rank/name")
    self.family   = None
    self.degree = None
    self.functional = None
    if self.type != "Constant":
      self.family = libspud.get_option(optionpath+"/type/rank/element/family")
      self.degree = libspud.get_option(optionpath+"/type/rank/element/degree")

    self.size     = None
    self.shape    = None
    self.symmetry = None
    if self.rank == "Vector":
      if libspud.have_option(optionpath+"/type/rank/element/size"):
        self.size = libspud.get_option(optionpath+"/type/rank/element/size")
    elif self.rank == "Tensor":
      if libspud.have_option(optionpath+"/type/rank/element/shape"):
        self.shape = libspud.get_option(optionpath+"/type/rank/element/shape")
      if libspud.have_option(optionpath+"/type/rank/element/symmetric"):
        self.symmetry = True

    self.enrichment_family = None
    self.enrichment_degree = None
    if libspud.have_option(optionpath+"/type/rank/element/enrichment"):
      self.enrichment_family = libspud.get_option(optionpath+"/type/rank/element/enrichment/element/family")
      self.enrichment_degree = libspud.get_option(optionpath+"/type/rank/element/enrichment/element/degree")

    # this should be restricted by the schema to Constant coefficients:
    if libspud.have_option(optionpath+"/type/rank/value/functional"):
      functional_optionpath = optionpath+"/type/rank/value/functional"
      functional = buckettools.spud.SpudFunctionalBucket()
      functional.fill(functional_optionpath, self.system, self)
      self.functional = functional
    
    self.cpp = []
    for k in range(libspud.option_count(optionpath+"/type/rank/initial_condition")):
      cpp_optionpath = optionpath+"/type/rank/initial_condition["+`k`+"]"
      if libspud.have_option(cpp_optionpath+"/cpp"):
        cpp_name = libspud.get_option(cpp_optionpath+"/name")
        cppexpression = buckettools.spud.SpudCppExpressionBucket()
        # get all the information about this expression from the options dictionary
        cppexpression.fill(cpp_optionpath, cpp_name, self)
        # let the field know about this cpp expression
        self.cpp.append(cppexpression)
        # done with this expression
        del cppexpression

    for j in range(libspud.option_count(optionpath+"/type/rank/boundary_condition")):
      bc_optionpath = optionpath+"/type/rank/boundary_condition["+`j`+"]"
      bc_name = libspud.get_option(bc_optionpath+"/name")
      for k in range(libspud.option_count(bc_optionpath+"/sub_components")):
        bc_comp_optionpath = bc_optionpath+"/sub_components["+`k`+"]"
        bc_comp_name = libspud.get_option(bc_comp_optionpath+"/name")
        
        cpp_optionpath = bc_comp_optionpath+"/type"
        if libspud.have_option(cpp_optionpath+"/cpp"):
          cpp_name = bc_name + bc_comp_name
          
          cppexpression = buckettools.spud.SpudCppExpressionBucket()
          # get all the information about this expression from the options dictionary
          cppexpression.fill(cpp_optionpath, cpp_name, self)
          # let the field know about this cpp expression
          self.cpp.append(cppexpression)
          # done with this expression
          del cppexpression

    for k in range(libspud.option_count(optionpath+"/type/rank/value")):
      cpp_optionpath = optionpath+"/type/rank/value["+`k`+"]"
      if libspud.have_option(cpp_optionpath+"/cpp"):
        cpp_name = libspud.get_option(cpp_optionpath+"/name")
        cppexpression = buckettools.spud.SpudCppExpressionBucket()
        # get all the information about this expression from the options dictionary
        cppexpression.fill(cpp_optionpath, cpp_name, self)
        # let the field know about this cpp expression
        self.cpp.append(cppexpression)
        # done with this expression
        del cppexpression
def get_opal_options():
    "Initialises the structure for the options."
    opal_options = Opal_input()
    nirom_options = Nirom_input()
    fwd_options = Forward_model_options()

    #Read the input data from the user
    opal_input_file = str(sys.argv[1])
    #Load the .opal file
    libspud.load_options(opal_input_file)
    ##Create Opal Variable
    #    opal_options = Opal_input()
    ##Start reading options
    print "reading opal input file", opal_input_file
    if libspud.have_option('/avoid_perturbing_near_wells'):
        opal_options.avoid_perturbing_near_wells = True

    if (libspud.have_option('/opal_operation/importance_map')):

        opal_options.opal_operation = 'importance_map'
        im_path = '/opal_operation/importance_map/'
        opal_options = read_in_importance_map_options(im_path, opal_options)

    elif (libspud.have_option('/opal_operation/data_assimilation')):

        opal_options.opal_operation = 'da'
        opal_options.data_assimilation.fwd_input_file = libspud.get_option(
            '/opal_operation/data_assimilation/fwd_input_file')
        #print "opal_options.data_assimilation.fwd_input_file", opal_options.data_assimilation.fwd_input_file

    elif (libspud.have_option('/opal_operation/nirom')):

        opal_options.opal_operation = 'nirom'
        nirom_path = 'opal_operation/nirom/'
        opal_options, nirom_options, fwd_options = read_in_nirom_options(
            nirom_path, opal_options, nirom_options, fwd_options)

    elif (libspud.have_option('/opal_operation/second_order_da')):

        opal_options.opal_operation = 'second_order_da'
        da_path = '/opal_operation/second_order_da/'
        opal_options = read_in_soda_options(da_path, opal_options)

    elif (libspud.have_option('/opal_operation/ga_optimisation')):
        opal_options.opal_operation = 'ga_optimisation'
        path = '/opal_operation/ga_optimisation'

        # previously these three options were at the top level
        opal_options.output_filename = libspud.get_option(path +
                                                          '/Output_filename')
        opal_options.executable = libspud.get_option(path + '/Executable')
        opal_options.input_file = libspud.get_option(path + '/Input_file')

        opal_options.ga_max_generations = libspud.get_option(
            path + '/convergence_settings/Maximum_generations')

        opal_options.ga_locations_to_study = libspud.get_option(
            path + '/Locations_to_study/value')
        if libspud.have_option(path + '/Locations_to_study/Initial_guess'):
            opal_options.ga_initial_guess = libspud.get_option(
                path + '/Locations_to_study/Initial_guess')
        if libspud.have_option(path + '/Locations_to_study/Mind_the_gap'):
            opal_options.mind_the_gap = libspud.get_option(
                path + '/Locations_to_study/Mind_the_gap')
        if libspud.have_option(path + '/Trelis_integration'):
            opal_options.trelis_path = libspud.get_option(
                path + '/Trelis_integration/trelis_path')
            opal_options.trelis_input_file = libspud.get_option(
                path + '/Trelis_integration/trelis_input_file')
        opal_options.optimise_input = libspud.have_option(path +
                                                          '/optimise_input')
        if libspud.have_option(path +
                               '/convergence_settings/Gradient_convergence'):
            opal_options.ga_gradient_convergence = libspud.get_option(
                path + '/convergence_settings/Gradient_convergence')
        if libspud.have_option(path +
                               '/convergence_settings/Absolute_convergence'):
            opal_options.ga_absolute_convergence = libspud.get_option(
                path + '/convergence_settings/Absolute_convergence')
        if libspud.have_option(path + '/Number_processors'):
            opal_options.number_processors = libspud.get_option(
                path + '/Number_processors')
            if libspud.have_option(path + '/Number_processors/MPI_runs'):
                opal_options.MPI_runs = libspud.get_option(
                    path + '/Number_processors/MPI_runs')
                opal_options.number_processors /= opal_options.MPI_runs
        opal_options.ga_population_generation = libspud.get_option(
            path + '/Population_generation')
        opal_options.ga_breeding_prob = libspud.get_option(
            path + '/Breeding_probability/value')
        if libspud.have_option(path +
                               '/Breeding_probability/Generation_method'):
            opal_options.generation_method = libspud.get_option(
                path + '/Breeding_probability/Generation_method')
        opal_options.ga_mutation_prob = libspud.get_option(
            path + '/Mutation_probability/value')
        if libspud.have_option(path + '/Mutation_probability/Mutation_method'):
            opal_options.mutation_method = libspud.get_option(
                path + '/Mutation_probability/Mutation_method')
        opal_options.precision = libspud.get_option(path + '/Precision')
        if libspud.have_option(path + '/Fitness/python_function'):
            opal_options.ga_fitness_functional = libspud.get_option(
                path + '/Fitness/python_function')
        opal_options.ga_Minimise = libspud.have_option(
            path + '/Fitness/Optimisation/Minimise')
        opal_options.producer_ids = libspud.get_option(path +
                                                       '/Fitness/producer_ids')
        opal_options.injector_ids = libspud.get_option(path +
                                                       '/Fitness/injector_ids')
        if libspud.have_option(path +
                               '/GA_methods/Evolutionary_algorithm/eaSimple'):
            opal_options.ga_evol_algorithm = 1
        elif libspud.have_option(
                path + '/GA_methods/Evolutionary_algorithm/eaMuCommaLambda'):
            opal_options.ga_evol_algorithm = 2
            opal_options.ga_mu = libspud.get_option(
                path + '/GA_methods/Evolutionary_algorithm/eaMuCommaLambda/Mu')
            opal_options.ga_lambda = libspud.get_option(
                path +
                '/GA_methods/Evolutionary_algorithm/eaMuCommaLambda/Lambda')
        elif libspud.have_option(
                path + '/GA_methods/Evolutionary_algorithm/eaMuPlusLambda'):
            opal_options.ga_evol_algorithm = 3
            opal_options.ga_mu = libspud.get_option(
                path + '/GA_methods/Evolutionary_algorithm/eaMuPlusLambda/Mu')
            opal_options.ga_lambda = libspud.get_option(
                path +
                '/GA_methods/Evolutionary_algorithm/eaMuPlusLambda/Lambda')
        if libspud.have_option(path + '/GA_methods/Selection_method/selBest'):
            opal_options.ga_selection_method = 1
        elif libspud.have_option(path +
                                 '/GA_methods/Selection_method/selNSGA2'):
            opal_options.ga_selection_method = 2
        elif libspud.have_option(path +
                                 '/GA_methods/Selection_method/selSPEA2'):
            opal_options.ga_selection_method = 3

        opal_options.ga_CMA = False
        if libspud.have_option(path + '/GA_methods/Use_CMA'):
            opal_options.ga_CMA = True
            opal_options.ga_centroid = libspud.get_option(
                path + '/GA_methods/Use_CMA/centroid')
            opal_options.ga_sigma = libspud.get_option(
                path + '/GA_methods/Use_CMA/sigma')
        if libspud.have_option(path + 'Hall_of_fame'):
            opal_options.ga_hall_of_fame = libspud.get_option(path +
                                                              'Hall_of_fame')
        nfields = libspud.option_count(path + '/Variables')
        for i in range(nfields):
            temp_field = ga_variable()
            fieldpath = path + '/Variables[' + str(i) + ']'
            temp_field.name = libspud.get_option(fieldpath + '/name')
            temp_field.min_limit = libspud.get_option(fieldpath + '/Min_limit')
            temp_field.max_limit = libspud.get_option(fieldpath + '/Max_limit')
            temp_field.variable_pattern = libspud.get_option(
                fieldpath + '/Variable_pattern')
            temp_field.normaliser = 1.0
            if libspud.have_option(fieldpath + '/normaliser'):
                temp_field.normaliser = libspud.get_option(fieldpath +
                                                           '/normaliser')
            ##Now append to the variables list
            opal_options.ga_variables.append(temp_field)

    libspud.clear_options()

    return opal_options, fwd_options, nirom_options
Example #27
0
def convert(fluidity_options_file_path, ff_options_file_path):

    # Read in Fluidity simulation options

    libspud.clear_options()
    libspud.load_options(fluidity_options_file_path)

    # Simulation name
    simulation_name = libspud.get_option("/simulation_name")

    # Geometry
    base = "/geometry"
    dimension = libspud.get_option(base + "/dimension")
    mesh_path = libspud.get_option(
        base + "/mesh::CoordinateMesh/from_file/file_name"
    ) + ".msh"  # FIXME: Always assumes gmsh format.

    # Function spaces
    velocity_function_space = FunctionSpace("/geometry", 1)
    freesurface_function_space = FunctionSpace("/geometry", 2)

    # Timestepping
    base = "/timestepping"
    current_time = libspud.get_option(base + "/current_time")
    timestep = libspud.get_option(base + "/timestep")
    finish_time = libspud.get_option(base + "/finish_time")

    ## Steady-state
    if (libspud.have_option(base + "/steady_state")):
        if (libspud.have_option(base + "/steady_state/tolerance")):
            steady_state = libspud.get_option(base + "/steady_state/tolerance")
        else:
            steady_state = 1e-7
    else:
        steady_state = None

    # I/O
    base = "/io"
    dump_format = libspud.get_option(base + "/dump_format")
    if (libspud.have_option(base + "/dump_period")):
        dump_period = libspud.get_option(base + "/dump_period/constant")
    elif (libspud.have_option(base + "/dump_period_in_timesteps")):
        dump_period = libspud.get_option(
            base + "/dump_period_in_timesteps/constant") * timestep
    else:
        print "Unable to obtain dump_period."
        sys.exit()

    # Gravity
    g_magnitude = libspud.get_option("/physical_parameters/gravity/magnitude")

    # Velocity field (momentum equation)
    base = "/material_phase[0]/vector_field::Velocity"

    ## Depth (free surface mean height)
    c = libspud.get_child_name(
        base +
        "/prognostic/equation::ShallowWater/scalar_field::BottomDepth/prescribed/value::WholeMesh/",
        1)
    depth = libspud.get_option(
        base +
        "/prognostic/equation::ShallowWater/scalar_field::BottomDepth/prescribed/value::WholeMesh/%s"
        % c)

    ## Bottom drag coefficient
    if (libspud.have_option(base +
                            "/prognostic/equation::ShallowWater/bottom_drag")):
        c = libspud.get_child_name(
            base +
            "/prognostic/equation::ShallowWater/bottom_drag/scalar_field::BottomDragCoefficient/prescribed/value::WholeMesh/",
            1)
        bottom_drag = libspud.get_option(
            base +
            "/prognostic/equation::ShallowWater/bottom_drag/scalar_field::BottomDragCoefficient/prescribed/value::WholeMesh/%s"
            % c)
    else:
        bottom_drag = None

    ## Viscosity
    if (libspud.have_option(base + "/prognostic/tensor_field::Viscosity")):
        viscosity = libspud.get_option(
            base +
            "/prognostic/tensor_field::Viscosity/prescribed/value::WholeMesh/anisotropic_symmetric/constant"
        )[0][0]
    else:
        viscosity = None

    ## Momentum source
    if (libspud.have_option(base + "/prognostic/vector_field::Source")):
        c = libspud.get_child_name(
            base +
            "/prognostic/vector_field::Source/prescribed/value::WholeMesh/", 1)
        momentum_source = libspud.get_option(
            base +
            "/prognostic/vector_field::Source/prescribed/value::WholeMesh/%s" %
            c)
    else:
        momentum_source = None

    ## Initial condition
    if (libspud.have_option(base +
                            "/prognostic/initial_condition::WholeMesh")):
        c = libspud.get_child_name(
            base + "/prognostic/initial_condition::WholeMesh/", 1)
        velocity_initial_condition = libspud.get_option(
            base + "/prognostic/initial_condition::WholeMesh/%s" % c)
    else:
        velocity_initial_condition = 0.0

    ## Boundary conditions
    number_of_bcs = libspud.option_count(base +
                                         "/prognostic/boundary_conditions")
    velocity_bcs = []
    for i in range(number_of_bcs):
        velocity_bcs.append(
            VelocityBoundaryCondition(base +
                                      "/prognostic/boundary_conditions[%d]" %
                                      i))

    # Pressure field (continuity equation)
    base = "/material_phase[0]/scalar_field::Pressure"
    integrate_by_parts = libspud.have_option(
        base +
        "/prognostic/spatial_discretisation/continuous_galerkin/integrate_continuity_by_parts"
    )

    ## Initial condition
    if (libspud.have_option(base +
                            "/prognostic/initial_condition::WholeMesh")):
        c = libspud.get_child_name(
            base + "/prognostic/initial_condition::WholeMesh/", 1)
        pressure_initial_condition = libspud.get_option(
            base + "/prognostic/initial_condition::WholeMesh/%s" % c)
    else:
        pressure_initial_condition = 0.0

    ## Boundary conditions
    number_of_bcs = libspud.option_count(base +
                                         "/prognostic/boundary_conditions")
    pressure_bcs = []
    for i in range(number_of_bcs):
        pressure_bcs.append(
            PressureBoundaryCondition(base +
                                      "/prognostic/boundary_conditions[%d]" %
                                      i))

    ## Continuity source
    if (libspud.have_option(base + "/prognostic/scalar_field::Source")):
        c = libspud.get_child_name(
            base +
            "/prognostic/scalar_field::Source/prescribed/value::WholeMesh/", 1)
        continuity_source = libspud.get_option(
            base +
            "/prognostic/scalar_field::Source/prescribed/value::WholeMesh/%s" %
            c)
    else:
        continuity_source = None

    # Write out to a Firedrake-Fluids simulation configuration file
    libspud.clear_options()

    # Create a bare-bones .swml file to add to.
    f = open(ff_options_file_path, "w")
    f.write("<?xml version='1.0' encoding='utf-8'?>\n")
    f.write("<shallow_water_options>\n")
    f.write("</shallow_water_options>\n")
    f.close()

    libspud.load_options(ff_options_file_path)

    # Simulation name
    libspud.set_option("/simulation_name", simulation_name)

    # Geometry
    base = "/geometry"
    libspud.set_option(base + "/dimension", dimension)
    libspud.set_option(base + "/mesh/from_file/relative_path", mesh_path)

    # Function spaces
    base = "/function_spaces"
    libspud.set_option(base + "/function_space::VelocityFunctionSpace/degree",
                       velocity_function_space.degree)
    libspud.set_option(base + "/function_space::VelocityFunctionSpace/family",
                       velocity_function_space.family)
    libspud.set_option(
        base + "/function_space::FreeSurfaceFunctionSpace/degree",
        freesurface_function_space.degree)
    libspud.set_option(
        base + "/function_space::FreeSurfaceFunctionSpace/family",
        freesurface_function_space.family)

    # I/O
    base = "/io"
    libspud.set_option(base + "/dump_format", dump_format)
    libspud.set_option(base + "/dump_period", dump_period)

    # Timestepping
    base = "/timestepping"
    print timestep
    libspud.set_option(base + "/current_time", current_time)
    try:
        libspud.set_option(base + "/timestep", timestep)
    except:
        pass
    libspud.set_option(base + "/finish_time", finish_time)

    ## Steady-state
    if (steady_state):
        libspud.set_option(base + "/steady_state/tolerance", steady_state)

    # Gravity
    libspud.set_option("/physical_parameters/gravity/magnitude", g_magnitude)

    # System/Core Fields: Velocity
    base = "/system/core_fields/vector_field::Velocity"

    ## Initial condition
    if (isinstance(velocity_initial_condition, str)):
        libspud.set_option(base + "/initial_condition/python",
                           velocity_initial_condition)
    else:
        libspud.set_option(base + "/initial_condition/constant",
                           velocity_initial_condition)

    ## Boundary conditions
    try:
        for i in range(len(velocity_bcs)):
            libspud.set_option(
                base +
                "/boundary_condition::%s/surface_ids" % velocity_bcs[i].name,
                velocity_bcs[i].surface_ids)
            libspud.set_option_attribute(
                base +
                "/boundary_condition::%s/type/name" % velocity_bcs[i].name,
                velocity_bcs[i].type)

            if (velocity_bcs[i].type == "dirichlet"):
                if (isinstance(velocity_bcs[i].value, str)):
                    libspud.set_option(
                        base +
                        "/boundary_condition::%s/type::dirichlet/value/python"
                        % velocity_bcs[i].name, velocity_bcs[i].value)
                else:
                    libspud.set_option(
                        base +
                        "/boundary_condition::%s/type::dirichlet/value/constant"
                        % velocity_bcs[i].name, velocity_bcs[i].value)
    except:
        pass

    # System/Core Fields: FreeSurfacePerturbation
    base = "/system/core_fields/scalar_field::FreeSurfacePerturbation"

    #FIXME: Pressure initial and boundary conditions are multiplied by 'g' in Fluidity, but not in Firedrake-Fluids.
    ## Initial condition
    if (isinstance(pressure_initial_condition, str)):
        libspud.set_option(base + "/initial_condition/python",
                           pressure_initial_condition)
    else:
        libspud.set_option(base + "/initial_condition/constant",
                           pressure_initial_condition)

    ## Boundary conditions
    try:
        for i in range(len(pressure_bcs)):
            libspud.set_option(
                base +
                "/boundary_condition::%s/surface_ids" % pressure_bcs[i].name,
                pressure_bcs[i].surface_ids)
            libspud.set_option(
                base +
                "/boundary_condition::%s/type/name" % pressure_bcs[i].name,
                pressure_bcs[i].type)

            if (pressure_bcs[i].type == "dirichlet"):
                if (isinstance(pressure_bcs[i].value, str)):
                    libspud.set_option(
                        base +
                        "/boundary_condition::%s/type::dirichlet/value/python"
                        % pressure_bcs[i].name, pressure_bcs[i].value)
                else:
                    libspud.set_option(
                        base +
                        "/boundary_condition::%s/type::dirichlet/value/constant"
                        % pressure_bcs[i].name, pressure_bcs[i].value)
    except:
        pass

    # System/Core Fields: FreeSurfaceMean
    base = "/system/core_fields/scalar_field::FreeSurfaceMean"
    if (isinstance(depth, str)):
        libspud.set_option(base + "/value/python", depth)
    else:
        libspud.set_option(base + "/value/constant", depth)

    # Equations: Continuity equation
    base = "/system/equations/continuity_equation"
    libspud.set_option(base + "/integrate_by_parts", integrate_by_parts)

    ## Source term
    if (continuity_source is not None):
        if (isinstance(continuity_source, str)):
            libspud.set_option(
                base + "/source_term/scalar_field::Source/value/python",
                continuity_source)
        else:
            libspud.set_option(
                base + "/source_term/scalar_field::Source/value/constant",
                continuity_source)

    # Equations: Momentum equation
    base = "/system/equations/momentum_equation"

    ## Viscosity
    if (viscosity is not None):
        if (isinstance(viscosity, str)):
            libspud.set_option(
                base + "/stress_term/scalar_field::Viscosity/value/python",
                viscosity)
        else:
            libspud.set_option(
                base + "/stress_term/scalar_field::Viscosity/value/constant",
                viscosity)

    ## Bottom drag
    if (bottom_drag is not None):
        if (isinstance(bottom_drag, str)):
            libspud.set_option(
                base +
                "/drag_term/scalar_field::BottomDragCoefficient/value/python",
                bottom_drag)
        else:
            libspud.set_option(
                base +
                "/drag_term/scalar_field::BottomDragCoefficient/value/constant",
                bottom_drag)

    ## Source term
    if (momentum_source is not None):
        if (isinstance(momentum_source, str)):
            libspud.set_option(
                base + "/source_term/vector_field::Source/value/python",
                momentum_source)
        else:
            libspud.set_option(
                base + "/source_term/vector_field::Source/value/constant",
                momentum_source)

    # Write all the applied options to file.
    libspud.write_options(ff_options_file_path)

    return
Example #28
0
#To load the vtu files and read the coordinates of the nodes
#vtu_data = vtktools.vtu("Input_Importance_map_1.vtu") ###Hardcoded
#coordinates = vtu_data.GetLocations()

#To get the mpml file
path = os.getcwd()
mpmlfile = get_mpml_filename(path)

libspud.load_options(mpmlfile + '.mpml')
meshname_base = libspud.get_option('/geometry[0]/mesh[0]/from_file/file_name')
NDIM = libspud.get_option('/geometry/dimension')
Dt_n = libspud.get_option('/timestepping/timestep')  #timestep
tlevel_begin = libspud.get_option('/timestepping/current_time')  #start time
tlevel_end = libspud.get_option('/timestepping/finish_time')  #end time
NSCALAR = libspud.option_count('/Field_to_study')
DELTA_T = libspud.get_option(
    '/io/dump_period_in_timesteps/constant'
)  ###change to point to checkpint file in unperturbed
libspud.clear_options()

DT = tlevel_end - tlevel_begin  #total simulation period
NTIME = int(DT / Dt_n) + 1  # number of timelevels


def get_coordinates(vtu_filename):
    vtu_data = vtktools.vtu(vtu_filename)
    coordinates = vtu_data.GetLocations()
    return vtu_data, coordinates

Example #29
0
import libspud
print libspud.__file__

libspud.load_options('test.flml')

libspud.print_options()

print libspud.number_of_children('/geometry')
print libspud.get_child_name('geometry', 0)

print libspud.option_count('/problem_type')
print libspud.have_option('/problem_type')

print libspud.get_option_type('/geometry/dimension')
print libspud.get_option_type('/problem_type')

print libspud.get_option_rank('/geometry/dimension')
print libspud.get_option_rank(
    '/physical_parameters/gravity/vector_field::GravityDirection/prescribed/value/constant'
)

print libspud.get_option_shape('/geometry/dimension')
print libspud.get_option_shape('/problem_type')

print libspud.get_option('/problem_type')
print libspud.get_option('/geometry/dimension')
libspud.set_option('/geometry/dimension', 3)
print libspud.get_option('/geometry/dimension')

list_path = '/material_phase::Material1/scalar_field::MaterialVolumeFraction/prognostic/boundary_conditions::LetNoOneLeave/surface_ids'
print libspud.get_option_shape(list_path)
Example #30
0
import libspud

libspud.load_options('test.flml')

#libspud.print_options()

assert libspud.get_option('/timestepping/timestep') == 0.025

assert libspud.get_number_of_children('/geometry') == 5
assert libspud.get_child_name('geometry', 0) == "dimension"

assert libspud.option_count('/problem_type') == 1
assert libspud.have_option('/problem_type')

assert libspud.get_option_type('/geometry/dimension') is int
assert libspud.get_option_type('/problem_type') is str

assert libspud.get_option_rank('/geometry/dimension') == 0
assert libspud.get_option_rank('/physical_parameters/gravity/vector_field::GravityDirection/prescribed/value/constant') == 1

assert libspud.get_option_shape('/geometry/dimension') == (-1, -1)
assert libspud.get_option_shape('/problem_type')[0] > 1
assert libspud.get_option_shape('/problem_type')[1] == -1

assert libspud.get_option('/problem_type') == "multimaterial"
assert libspud.get_option('/geometry/dimension') == 2
libspud.set_option('/geometry/dimension', 3)


assert libspud.get_option('/geometry/dimension') == 3