Exemplo n.º 1
0
// Returns true if the given value string matches a "true" boolean value.
static bool ValueIsTrue(const char* value)
{
  return ((strcmp(value, "1") == 0) || 
          AlquimiaCaseInsensitiveStringCompare(value, "true") ||
          AlquimiaCaseInsensitiveStringCompare(value, "yes") ||
          AlquimiaCaseInsensitiveStringCompare(value, "on")) ? true : false;
}
Exemplo n.º 2
0
int main(int argc, char* argv[])
{
    if (argc == 1)
        Usage();

    // Initialize PETSc/MPI for command line options and engines that
    // require it.
    char help[] = "Alquimia advective, nondispersive reactive transport driver";
    PetscInitialize(&argc, &argv, (char*)0, help);
    PetscInitializeFortran();

    char input_file[FILENAME_MAX];
    strncpy(input_file, argv[1], FILENAME_MAX-1);

    // Parse the input file.
    TransportDriverInput* input = TransportDriverInput_New(input_file);
    if (input == NULL)
        alquimia_error("transport: error encountered reading input file '%s'.", input_file);

    // Set up output.
    DriverOutput* output = NULL;
    if (AlquimiaCaseInsensitiveStringCompare(input->output_type, "python"))
        output = PythonDriverOutput_New();
    else if (AlquimiaCaseInsensitiveStringCompare(input->output_type, "gnuplot"))
        output = GnuplotDriverOutput_New();

    // Create a TransportDriver from the parsed input.
    TransportDriver* transport = TransportDriver_New(input);

    // Run the simulation.
    int status = TransportDriver_Run(transport);

    // Get the solution out of the driver and write it out.
    if (output != NULL)
    {
        double final_time;
        AlquimiaVectorString var_names = {.size = 0};
        AlquimiaVectorDouble var_data = {.size = 0};
        TransportDriver_GetSoluteAndAuxData(transport, &final_time, &var_names, &var_data);
        DriverOutput_WriteMulticompVector(output, input->output_file, var_names, var_data);

        FreeAlquimiaVectorString(&var_names);
        FreeAlquimiaVectorDouble(&var_data);
    }

    // Clean up.
    TransportDriverInput_Free(input);
    TransportDriver_Free(transport);
    PetscInt petsc_error = PetscFinalize();
    if (status == EXIT_SUCCESS && petsc_error == 0)
        printf("Success!\n");
    else
        printf("Failed!\n");

    return status;
}
Exemplo n.º 3
0
TransportDriverInput* TransportDriverInput_New(const char* input_file)
{
  TransportDriverInput* input = malloc(sizeof(TransportDriverInput));
  memset(input, 0, sizeof(TransportDriverInput));

  // Make sure we have some meaningful defaults.
  input->hands_off = true; // Hands-off by default.
  input->t_min = 0.0;
  input->max_steps = INT_MAX;
  input->dt = FLT_MAX;
  input->cfl_factor = 1.0;
  input->porosity = 1.0;
  input->saturation = 1.0;
  input->temperature = 25.0;
  input->velocity = 0.0;
  input->left_bc_name = NULL;
  input->right_bc_name = NULL;
  input->cation_exchange_capacity = 0.0;
  input->surface_site_density = 0.0;
  input->output_type = NULL;
  input->output_file = NULL;

  // Fill in fields by parsing the input file.
  int error = ini_parse(input_file, ParseInput, input);
  if (error != 0)
  {
    TransportDriverInput_Free(input);
    alquimia_error("TransportDriver: Error parsing input: %s", input_file);
  }

  // Verify that our required fields are filled properly.
  if (!input->hands_off)
    alquimia_error("TransportDriver: simulation->hands_off must be set to true at the moment.");
  if (input->t_max <= input->t_min)
    alquimia_error("TransportDriver: simulation->t_max must be greater than simulation->t_min.");
  if (input->max_steps < 0)
    alquimia_error("TransportDriver: simulation->max_steps must be non-negative.");
  if ((input->cfl_factor <= 0.0) || (input->cfl_factor > 1.0))
    alquimia_error("TransportDriver: simulation->cfl_factor must be within (0, 1].");
  if (input->x_max <= input->x_min)
    alquimia_error("TransportDriver: domain->x_max must be greater than domain->x_min.");
  if (input->num_cells <= 0)
    alquimia_error("TransportDriver: domain->num_cells must be positive.");
  if ((input->porosity <= 0.0) || (input->porosity > 1.0))
    alquimia_error("TransportDriver: material->porosity must be within (0, 1].");
  if ((input->saturation <= 0.0) || (input->saturation > 1.0))
    alquimia_error("TransportDriver: material->saturation must be within (0, 1].");
  if (input->temperature <= 0.0)
    alquimia_error("TransportDriver: flow->temperature must be positive.");
  if ((input->left_bc_name == NULL) && (input->right_bc_name == NULL) && (input->velocity != 0.0))
    alquimia_error("TransportDriver: When velocity != 0, left or right boundary condition must be given.");

  // Default output.
  if (input->output_type == NULL)
    input->output_type = AlquimiaStringDup("gnuplot");
  char default_output_file[FILENAME_MAX];
  if (input->output_file == NULL)
  {
    // Find the last '.' in the input filename.
    int dot = strlen(input_file)-1;
    while ((dot > 0) && (input_file[dot] != '.')) --dot;
    char suffix[16];

    // Determine the suffix from the output type.
    if (AlquimiaCaseInsensitiveStringCompare(input->output_type, "gnuplot"))
      sprintf(suffix, ".gnuplot");
    else if (AlquimiaCaseInsensitiveStringCompare(input->output_type, "python"))
      sprintf(suffix, ".py");

    // Append the suffix.
    if (dot == 0)
      sprintf(default_output_file, "%s%s", input_file, suffix);
    else
    {
      memcpy(default_output_file, input_file, sizeof(char) * dot);
      strcat(default_output_file, suffix);
    }

    // Python modules can't have hyphens in their names, so we replace them 
    // with underscores.
    if (AlquimiaCaseInsensitiveStringCompare(input->output_type, "python"))
    {
      int len = strlen(default_output_file);
      for (int i = 0; i < len; ++i)
      {
        if (default_output_file[i] == '-')
          default_output_file[i] = '_';
      }
    }

    input->output_file = AlquimiaStringDup(default_output_file);
  }

  return input;
}