class FactoryTester(unittest.TestCase):
  def setUp(self):
    self.factory = Factory()

  ## Tests the createParametersObject() function without a type parameter
  def testCreateParametersObjectWithNoTypeParam(self):
    params = {"gamma" : "1.4", "R" : "200"}
    self.factory.createParametersObject("IdealGasEoS", params)

  ## Tests the createParametersObject() function with a type parameter
  def testCreateParametersObjectWithTypeParam(self):
    params = {"type" : "IdealGasEoS", "gamma" : "1.4", "R" : "200"}
    object_class = params["type"]
    self.factory.createParametersObject(object_class, params)

  ## Tests the createObject() function
  def testCreateObject(self):
    params = {"type" : "IdealGasEoS", "gamma" : "1.4", "R" : "200"}
    object_class = params["type"]
    self.factory.createObject(object_class, params)

  ## Tests the createObjectFromParametersObject() function
  def testCreateObjectFromParametersObject(self):
    object_class = "IdealGasEoS"
    parameters_object = self.factory.createParametersObject(object_class)
    parameters_object.set("gamma", 1.4)
    parameters_object.set("R", 200)
    self.factory.createObjectFromParametersObject(object_class, parameters_object)
def outputPrintDoFVectorToFile(path):
    # area function
    def A(x):
        return 2.0

    # create the DoF handler
    factory = Factory()
    n_cell = 5
    mesh = factory.createObject("UniformMesh", {
        "name": "mesh",
        "n_cell": n_cell
    })
    dof_handler = factory.createObject("DoFHandler1Phase", {
        "meshes": [mesh],
        "A": A
    })

    # solution vector
    U = range((n_cell + 1) * 3)

    # capture the output
    captor = OutputCaptor()
    printDoFVector(U, dof_handler)
    out = captor.getCapturedOutput()

    # write the output file
    text_file = open(path + "print_dof_vector.txt", "w")
    text_file.write(out)
    text_file.close()
    def testJunctionConstraintDoFIndices(self):
        # create the factory
        factory = Factory()

        # create the meshes
        n_cells_list = [3, 5, 4]
        meshes = list()
        for i, n_cells in enumerate(n_cells_list):
            name = "mesh" + str(i + 1)
            params = {"name": name, "n_cell": n_cells}
            meshes.append(factory.createObject("UniformMesh", params))

        # area function
        def A(x):
            return 2.0

        # create the DoF handler
        params = {"meshes": meshes, "A": A}
        dof_handler = factory.createObject("DoFHandler1Phase", params)

        # create an EoS
        eos_list = [factory.createObject("TestEoS", {})]

        # create the junctions
        n_constraints_list = [2, 6, 3]
        meshes_list = [["mesh1", "mesh2"], ["mesh2", "mesh3"],
                       ["mesh1", "mesh2"]]
        sides_list = [["right", "left"]] * 3
        junctions = list()
        for i in xrange(3):
            params = {
                "mesh_names": meshes_list[i],
                "mesh_sides": sides_list[i],
                "dof_handler": dof_handler,
                "eos_list": eos_list,
                "n_constraints": n_constraints_list[i]
            }
            junctions.append(factory.createObject("TestJunction", params))

        # update the DoF handler with the junction constraints
        dof_handler.updateWithJunctionConstraints(junctions)

        # check all of the constraint DoF indices are the expected
        expected_constraint_dof_indices = [[12, 13], [35, 36, 37, 38, 39, 40],
                                           [14, 15, 16]]
        for i, junction in enumerate(junctions):
            self.assertEqual(junction.i_constraint,
                             expected_constraint_dof_indices[i])
Exemple #4
0
def run(input_file, mods=list()):
    # parse the input file
    input_file_parser = InputFileParser()
    input_file_parser.parse(input_file)

    # apply modifications to input parameters, if any
    for mod in mods:
        input_file_parser.applyModification(mod)

    # create the factory
    factory = Factory()

    # equation of state
    eos_param_data = input_file_parser.getBlockData("EoS")
    eos_class = eos_param_data["type"]
    eos = factory.createObject(eos_class, eos_param_data)

    # thermodynamic state
    state_data = input_file_parser.getBlockData("ThermodynamicState")
    state = factory.createObject("ThermodynamicState", state_data)
    state.computeRemainingProperties(eos)
    print state
Exemple #5
0
    def checkJacobian(self,
                      bc_name,
                      model_type=ModelType.OnePhase,
                      phase=0,
                      boundary="right",
                      bc_params=dict(),
                      fd_eps=1e-8):
        self.model_type = model_type
        self.phase = phase

        # factory
        factory = Factory()

        # mesh
        params = {"n_cell": 1}
        meshes = [factory.createObject("UniformMesh", params)]

        # test node index
        if boundary == "left":
            k_test = 0
        else:
            k_test = 1

        # area function
        def A(x):
            return 2.0

        # DoF handler
        dof_handler_params = {"meshes": meshes, "A": A}
        if self.model_type == ModelType.OnePhase:
            dof_handler_class = "DoFHandler1Phase"
        elif self.model_type == ModelType.TwoPhaseNonInteracting:
            dof_handler_class = "DoFHandler2PhaseNonInteracting"

            def vf1_initial(x):
                return 0.3

            dof_handler_params["initial_vf1"] = vf1_initial
        elif self.model_type == ModelType.TwoPhase:
            dof_handler_class = "DoFHandler2Phase"
        dof_handler = factory.createObject(dof_handler_class,
                                           dof_handler_params)
        n_dof = dof_handler.n_dof
        n_var = dof_handler.n_var

        # equation of state
        eos_params = dict()
        eos_params["gamma"] = 1.4
        eos_params["R"] = 2.0
        eos_list = [factory.createObject("IdealGasEoS", eos_params)]

        # BC
        bc_params["mesh_name"] = meshes[0].name
        bc_params["boundary"] = boundary
        bc_params["dof_handler"] = dof_handler
        bc_params["eos_list"] = eos_list
        bc_params["phase"] = phase
        bc = factory.createObject(bc_name, bc_params)

        # compute base solution
        U = np.zeros(n_dof)
        for i in xrange(n_dof):
            U[i] = i + 1.0

        # base calculation
        r = np.zeros(n_dof)
        J_hand_coded = np.zeros(shape=(n_dof, n_dof))
        bc.applyWeakBC(U, r, J_hand_coded)

        # finite difference Jacobians
        rel_diffs = np.zeros(shape=(n_var, n_var))
        J_fd = np.zeros(shape=(n_var, n_var))
        for var_index_j in xrange(dof_handler.n_var):
            # solution index to perturb
            j = dof_handler.i(k_test, var_index_j)

            # perturb solution
            U_perturbed = deepcopy(U)
            U_perturbed[j] += fd_eps

            # compute finite difference Jacobian
            r_perturbed = np.zeros(n_dof)
            J_perturbed = np.zeros(shape=(n_dof, n_dof))
            bc.applyWeakBC(U_perturbed, r_perturbed, J_perturbed)
            for var_index_i in xrange(n_var):
                # residual index tested
                i = dof_handler.i(k_test, var_index_i)

                J_fd[var_index_i][var_index_j] = (r_perturbed[i] -
                                                  r[i]) / fd_eps
                rel_diffs[var_index_i][
                    var_index_j] = computeRelativeDifference(
                        J_hand_coded[i][j], J_fd[var_index_i][var_index_j])

        # print results
        if self.verbose:
            for var_index_i in xrange(n_var):
                i = dof_handler.i(k_test, var_index_i)
                var_i = dof_handler.variable_names[var_index_i]
                print "\nEquation variable:", var_i
                for var_index_j in xrange(n_var):
                    j = dof_handler.i(k_test, var_index_j)
                    var_j = dof_handler.variable_names[var_index_j]
                    print "\n  Derivative variable:", var_j
                    print "    Hand-coded        =", J_hand_coded[i][j]
                    print "    Finite difference =", J_fd[var_index_i][
                        var_index_j]
                    print "    Rel. difference   =", rel_diffs[var_index_i][
                        var_index_j]

        # take the absolute value of the relative differences
        return abs(rel_diffs)
    def checkDerivatives(self,
                         kernel_name,
                         model_type,
                         phase,
                         aux_dependencies,
                         aux_gradients=list(),
                         kernel_params=dict(),
                         fd_eps=1e-8):
        self.model_type = model_type
        self.phase = phase

        # factory
        factory = Factory()

        # mesh
        params = {"n_cell": 1}
        meshes = [factory.createObject("UniformMesh", params)]

        # area function
        def A(x):
            return 2.0

        # DoF handler
        dof_handler_params = {"meshes": meshes, "A": A}
        if self.model_type == ModelType.OnePhase:
            dof_handler_class = "DoFHandler1Phase"
        elif self.model_type == ModelType.TwoPhaseNonInteracting:
            dof_handler_class = "DoFHandler2PhaseNonInteracting"

            def vf1_initial(x):
                return 0.3

            dof_handler_params["initial_vf1"] = vf1_initial
        elif self.model_type == ModelType.TwoPhase:
            dof_handler_class = "DoFHandler2Phase"
        dof_handler = factory.createObject(dof_handler_class,
                                           dof_handler_params)

        # quadrature
        quadrature_params = {}
        quadrature = factory.createObject("Quadrature", quadrature_params)

        # FE values
        fe_values_params = {
            "quadrature": quadrature,
            "dof_handler": dof_handler,
            "meshes": meshes
        }
        self.fe_values = factory.createObject("FEValues", fe_values_params)

        # kernel
        kernel_params["phase"] = phase
        kernel_params["dof_handler"] = dof_handler
        kernel = factory.createObject(kernel_name, kernel_params)

        # aux
        aux_list = list()
        for a, aux_name in enumerate(aux_dependencies):
            # "vf1" is a special case of aux because its name is also the name of
            # a solution variable (in 2-phase); therefore one needs to make sure that
            # it uses its own "identity" aux instead of the generic test aux
            if aux_name == "vf1":
                params = {"phase": 0}
                aux_list.append(
                    factory.createObject("VolumeFractionPhase1", params))
            else:
                params = TestAuxParameters()
                params.set("var", aux_name)
                params.set("other_vars", aux_dependencies[aux_name])
                coefs = list()
                for d, dependency in enumerate(aux_dependencies[aux_name]):
                    coefs.append(a + 2.0 + d * 0.5)
                params.set("coefs", coefs)
                params.set("b", 1.0)
                aux_list.append(TestAux(params))

        # add the aux derivatives
        for aux_name in aux_gradients:
            params = {
                "aux": aux_name,
                "variable_names": aux_dependencies[aux_name]
            }
            aux_list.append(factory.createObject("AuxGradient", params))

        # data
        data = dict()
        aux_names = [aux.name for aux in aux_list]
        der = dof_handler.initializeDerivativeData(aux_names)
        self.elem = 0
        i = 0
        j = 1
        q = 0
        data["grad_A"] = 0.3
        data["phi"] = self.fe_values.get_phi()
        data["grad_phi"] = self.fe_values.get_grad_phi(self.elem)
        data["JxW"] = self.fe_values.get_JxW(self.elem)

        # compute base solution
        U = np.zeros(dof_handler.n_dof)
        for k in xrange(dof_handler.n_dof):
            U[k] = k + 1.0
        self.computeSolutionDependentData(U, data)
        for aux in aux_list:
            aux.compute(data, der)

        # base calculation
        r = kernel.computeResidual(data, i)[q]
        J_hand_coded = dict()
        for var_index in kernel.var_indices:
            J_hand_coded[var_index] = kernel.computeJacobian(
                data, der, var_index, i, j)[q]

        # finite difference Jacobians
        rel_diffs = dict()
        J_fd = dict()
        for var_index in kernel.var_indices:
            # perturb solution and recompute aux
            U_perturbed = deepcopy(U)
            j_global = dof_handler.i(j, var_index)
            U_perturbed[j_global] += fd_eps
            self.computeSolutionDependentData(U_perturbed, data)
            for aux in aux_list:
                aux.compute(data, der)

            # compute finite difference Jacobian
            r_perturbed = kernel.computeResidual(data, i)[q]
            J_fd[var_index] = (r_perturbed - r) / fd_eps
            rel_diffs[var_index] = computeRelativeDifference(
                J_hand_coded[var_index], J_fd[var_index])

        # print results
        if self.verbose:
            for var_index in kernel.var_indices:
                var = dof_handler.variable_names[var_index]
                print "\nDerivative variable:", var
                print "  Hand-coded        =", J_hand_coded[var_index]
                print "  Finite difference =", J_fd[var_index]
                print "  Rel. difference   =", rel_diffs[var_index]

        # take the absolute value of the relative differences
        for x in rel_diffs:
            rel_diffs[x] = abs(rel_diffs[x])
        return rel_diffs
    def checkJacobian(self,
                      test_option,
                      model_type=ModelType.OnePhase,
                      phase=0,
                      junction_params=dict(),
                      fd_eps=1e-8):
        # factory
        factory = Factory()

        # meshes
        params1 = {"n_cell": 1, "name": "mesh1"}
        params2 = {"n_cell": 1, "name": "mesh2"}
        meshes = [
            factory.createObject("UniformMesh", params1),
            factory.createObject("UniformMesh", params2)
        ]

        # area function
        def A(x):
            return 0.2

        # DoF handler
        dof_handler_params = {"meshes": meshes, "A": A}
        if model_type == ModelType.OnePhase:
            dof_handler_class = "DoFHandler1Phase"
        elif model_type == ModelType.TwoPhaseNonInteracting:
            dof_handler_class = "DoFHandler2PhaseNonInteracting"

            def vf1_initial(x):
                return 0.3

            dof_handler_params["initial_vf1"] = vf1_initial
        elif model_type == ModelType.TwoPhase:
            dof_handler_class = "DoFHandler2Phase"
        dof_handler = factory.createObject(dof_handler_class,
                                           dof_handler_params)
        n_dof = dof_handler.n_dof

        # equation of state
        eos_params1 = {"slope_initial": 1.0, "slope_increment": 0.1}
        eos_list = [factory.createObject("TestEoS", eos_params1)]
        if model_type != ModelType.OnePhase:
            eos_params2 = {"slope_initial": 1.1, "slope_increment": 0.07}
            eos_list.append(factory.createObject("TestEoS", eos_params2))

        # junction
        junction_params["mesh_names"] = " ".join(
            [mesh.name for mesh in meshes])
        junction_params["mesh_sides"] = "right left"
        junction_params["dof_handler"] = dof_handler
        junction_params["eos_list"] = eos_list
        junction_parameters = factory.createParametersObject(
            self.junction_name)
        for param in junction_params:
            junction_parameters.set(param, junction_params[param])
        if junction_parameters.hasRegisteredParam("phase"):
            junction_parameters.set("phase", phase)
        junction = factory.createObjectFromParametersObject(
            self.junction_name, junction_parameters)

        # update DoF handler with junction constraints
        dof_handler.updateWithJunctionConstraints([junction])

        # compute base solution
        U = np.zeros(n_dof)
        U_old = np.zeros(n_dof)
        for i in xrange(n_dof):
            U[i] = i + 1.0
            U_old[i] = i + 2.0

        # determine evaluation function
        if test_option == "weak":
            f = junction.applyWeaklyToNonlinearSystem
        elif test_option == "strong":
            f = junction.applyStronglyToNonlinearSystem
        elif test_option == "both":

            def f(*args, **kwargs):
                junction.applyWeaklyToNonlinearSystem(*args, **kwargs)
                junction.applyStronglyToNonlinearSystem(*args, **kwargs)
        else:
            error("Invalid test option")

        # base calculation
        r = np.zeros(n_dof)
        J_hand_coded = np.zeros(shape=(n_dof, n_dof))
        f(U, U_old, r, J_hand_coded)

        # finite difference Jacobians
        rel_diffs = np.zeros(shape=(n_dof, n_dof))
        J_fd = np.zeros(shape=(n_dof, n_dof))
        for j in xrange(n_dof):
            # perturb solution
            U_perturbed = deepcopy(U)
            U_perturbed[j] += fd_eps

            # compute finite difference Jacobian
            r_perturbed = np.zeros(n_dof)
            J_perturbed = np.zeros(shape=(n_dof, n_dof))
            f(U_perturbed, U_old, r_perturbed, J_perturbed)
            for i in xrange(n_dof):
                J_fd[i, j] = (r_perturbed[i] - r[i]) / fd_eps

        # compute difference matrices
        abs_diffs = abs(J_hand_coded - J_fd)
        rel_diffs = computeRelativeDifferenceMatrix(J_hand_coded, J_fd)

        # print results
        if self.verbose:
            print "\nRelative difference of Jacobian for " + test_option + " contributions:"
            printRelativeMatrixDifference(rel_diffs, abs_diffs, 1e-1, 1e-3)

        matched = np.zeros((n_dof, n_dof), dtype=bool)
        for i in xrange(n_dof):
            for j in xrange(n_dof):
                matched[i, j] = abs_diffs[i, j] < self.abs_tol or rel_diffs[
                    i, j] < self.rel_tol

        return matched
Exemple #8
0
def run(input_file, mods=list()):
  # parse the input file
  input_file_parser_original = InputFileParser()
  input_file_parser_original.parse(input_file)

  # check if the input file was a differential input file
  if input_file_parser_original.blockExists("BaseInputFile"):
    # get the name of the base input file and parse it
    base_input_file = input_file_parser_original.getBlockData("BaseInputFile")["base"]
    input_file_parser_base = InputFileParser()
    input_file_parser_base.parse(base_input_file)

    # apply modifications to base input file parser
    input_file_parser_base.applyDifferentialInputFileParser(input_file_parser_original)

    input_file_parser = input_file_parser_base
  else:
    input_file_parser = input_file_parser_original

  # apply modifications to input parameters, if any
  for mod in mods:
    input_file_parser.applyModification(mod)

  # create the factory
  factory = Factory()

  # model
  model_param_data = input_file_parser.getBlockData("Model")
  model = factory.createObject("Model", model_param_data)
  model_type = model.model_type

  # mesh(es)
  mesh_subblocks = input_file_parser.getSubblockNames("Mesh")
  if len(mesh_subblocks) == 0:
    # single mesh; no subblock is required
    mesh_param_data = input_file_parser.getBlockData("Mesh")
    mesh_class = mesh_param_data["type"]
    mesh = factory.createObject(mesh_class, mesh_param_data)
    meshes = [mesh]
  else:
    # multiple meshes; subblocks are required
    meshes = list()
    for mesh_subblock in mesh_subblocks:
      mesh_param_data = input_file_parser.getSubblockData("Mesh", mesh_subblock)
      mesh_class = mesh_param_data["type"]
      mesh_param_data["name"] = mesh_subblock
      mesh = factory.createObject(mesh_class, mesh_param_data)
      meshes.append(mesh)
  # check that no meshes have the same name
  mesh_names = list()
  for mesh in meshes:
    if mesh.name in mesh_names:
      error("Multiple meshes with the name '" + mesh.name + "'.")
    else:
      mesh_names.append(mesh.name)

  # equations of state
  eos_subblocks = input_file_parser.getSubblockNames("EoS")
  if model_type == ModelType.OnePhase:
    if len(eos_subblocks) != 1:
      error("Single-phase flow should have exactly 1 equation of state.")
  else:
    if len(eos_subblocks) != 2:
      error("Two-phase flow should have exactly 2 equations of state.")
  eos_list = list()
  phase_name_to_index = dict()
  for k, eos_subblock in enumerate(eos_subblocks):
    phase_name_to_index[eos_subblock] = k
    eos_param_data = input_file_parser.getSubblockData("EoS", eos_subblock)
    eos_class = eos_param_data["type"]
    eos_list.append(factory.createObject(eos_class, eos_param_data))

  # initial conditions / initial guess
  ic_param_data = input_file_parser.getBlockData("IC")
  if model_type == ModelType.OnePhase:
    ics = factory.createObject("InitialConditions1Phase", ic_param_data)
  else:
    ics = factory.createObject("InitialConditions2Phase", ic_param_data)

  # DoF handler
  dof_handler_params = {"meshes": meshes, "A": ics.A}
  if model_type == ModelType.OnePhase:
    dof_handler_class = "DoFHandler1Phase"
  elif model_type == ModelType.TwoPhaseNonInteracting:
    dof_handler_class = "DoFHandler2PhaseNonInteracting"
    dof_handler_params["initial_vf1"] = ics.vf1
  elif model_type == ModelType.TwoPhase:
    dof_handler_class = "DoFHandler2Phase"
  dof_handler = factory.createObject(dof_handler_class, dof_handler_params)

  # junctions
  junctions = list()
  if input_file_parser.blockExists("Junctions"):
    junction_subblocks = input_file_parser.getSubblockNames("Junctions")
    for junction_subblock in junction_subblocks:
      junction_param_data = input_file_parser.getSubblockData("Junctions", junction_subblock)
      junction_class = junction_param_data["type"]
      if "phase" in junction_param_data:
        junction_param_data["phase"] = phase_name_to_index[junction_param_data["phase"]]
      junction_param_data["dof_handler"] = dof_handler
      junction_param_data["eos_list"] = eos_list

      junction = factory.createObject(junction_class, junction_param_data)
      junctions.append(junction)

  # update DoF handler with junction constraints
  dof_handler.updateWithJunctionConstraints(junctions)

  # boundary conditions
  bcs = list()
  bc_subblocks = input_file_parser.getSubblockNames("BC")
  for bc_subblock in bc_subblocks:
    bc_param_data = input_file_parser.getSubblockData("BC", bc_subblock)
    bc_class = bc_param_data["type"]

    # if there is only 1 mesh, add the mesh parameter if not supplied already
    if len(meshes) == 1:
      if "mesh_name" not in bc_param_data:
        bc_param_data["mesh_name"] = meshes[0].name

    if "phase" in bc_param_data:
      bc_param_data["phase"] = phase_name_to_index[bc_param_data["phase"]]
    bc_param_data["dof_handler"] = dof_handler
    bc_param_data["eos_list"] = eos_list

    bc = factory.createObject(bc_class, bc_param_data)
    bcs.append(bc)

  # interface closures
  if model_type == ModelType.TwoPhase:
    interface_closures_params = input_file_parser.getBlockData("InterfaceClosures")
    interface_closures_params["factory"] = factory
    interface_closures_class = interface_closures_params["type"]
    interface_closures = factory.createObject(interface_closures_class, interface_closures_params)
  else:
    interface_closures = None

  # gravity
  physics_param_data = input_file_parser.getBlockData("Physics")
  physics_params = factory.createParametersObject("Physics", physics_param_data)
  gravity = physics_params.get("gravity")

  # nonlinear solver options
  nonlinear_solver_params = input_file_parser.getBlockData("NonlinearSolver")

  # stabilization
  if input_file_parser.blockExists("Stabilization"):
    stabilization_param_data = input_file_parser.getBlockData("Stabilization")
    stabilization_param_data["factory"] = factory
    stabilization_param_data["dof_handler"] = dof_handler
    stabilization_param_data["model_type"] = model_type
    stabilization_class = stabilization_param_data["type"]
  else:
    stabilization_param_data = {"factory": factory, "dof_handler": dof_handler, "model_type": model_type}
    stabilization_class = "NoStabilization"
  stabilization = factory.createObject(stabilization_class, stabilization_param_data)

  # create and run the executioner
  executioner_param_data = input_file_parser.getBlockData("Executioner")
  executioner_type = executioner_param_data["type"]
  executioner_param_data["model"] = model
  executioner_param_data["ics"] = ics
  executioner_param_data["bcs"] = bcs
  executioner_param_data["junctions"] = junctions
  executioner_param_data["eos_list"] = eos_list
  executioner_param_data["interface_closures"] = interface_closures
  executioner_param_data["gravity"] = gravity
  executioner_param_data["dof_handler"] = dof_handler
  executioner_param_data["meshes"] = meshes
  executioner_param_data["nonlinear_solver_params"] = nonlinear_solver_params
  executioner_param_data["stabilization"] = stabilization
  executioner_param_data["factory"] = factory
  executioner = factory.createObject(executioner_type, executioner_param_data)
  U = executioner.run()

  # create and run the output
  output_param_data = input_file_parser.getBlockData("Output")
  output_param_data["model"] = model
  output_param_data["eos_list"] = eos_list
  output_param_data["dof_handler"] = dof_handler
  output_param_data["meshes"] = meshes
  output = factory.createObject("Output", output_param_data)
  output.run(U)