Beispiel #1
0
void Input_CreateAlquimiaInterface(const char* input_file,
                                   AlquimiaInterface* engine_interface,
                                   AlquimiaSizes* engine_sizes,
                                   AlquimiaEngineFunctionality* engine_functionality,
                                   AlquimiaEngineStatus* engine_status)
{
  // Get the engine and other parameters.
  EngineData data;
  int error = ini_parse(input_file, ParseEngineData, &data);
  if (error != 0)
    alquimia_error("Input_CreateAlqumiaInterface: Error parsing input: %s", input_file);

  // Initialize the engine.
  CreateAlquimiaInterface(data.engine_name, engine_interface, engine_status);
  if (engine_status->error != 0) 
    alquimia_error("Input_CreateAlquimiaInterface: %s", engine_status->message);

  // Set it up with our parameters and retrieve functionality.
  engine_interface->Setup(data.input_file,
                          data.hands_off,
                          engine_interface,
                          engine_sizes,
                          engine_functionality,
                          engine_status);

  if (engine_status->error != 0) 
    alquimia_error("Input_CreateAlquimiaInterface: %s", engine_status->message);
}
Beispiel #2
0
TransportDriver* TransportDriver_New(TransportDriverInput* input)
{
  TransportDriver* driver = malloc(sizeof(TransportDriver));

  // Get basic simulation parameters.
  driver->description = AlquimiaStringDup(input->description);
  driver->coupling = input->coupling;
  driver->t_min = input->t_min; 
  driver->t_max = input->t_max;
  driver->max_steps = input->max_steps;
  driver->dt = input->dt;
  driver->cfl = input->cfl_factor;
  driver->verbose = input->verbose;

  // Get grid information.
  driver->x_min = input->x_min; 
  driver->x_max = input->x_max;
  driver->num_cells = input->num_cells;

  // Get material properties.
  driver->porosity = input->porosity;
  driver->saturation = input->saturation;

  // Get flow variables.
  driver->vx = input->velocity;
  driver->temperature = input->temperature;

  // Simulation state.
  driver->time = driver->t_min;
  driver->step = 0;

  // Set up the chemistry engine.
  AllocateAlquimiaEngineStatus(&driver->chem_status);
  CreateAlquimiaInterface(input->chemistry_engine, &driver->chem, &driver->chem_status);
  if (driver->chem_status.error != 0) 
  {
    alquimia_error("TransportDriver_New: %s", driver->chem_status.message);
    return NULL;
  }

  // Set up the engine and get storage requirements.
  AlquimiaEngineFunctionality chem_engine_functionality;
  driver->chem.Setup(input->chemistry_input_file,
                     input->hands_off,
                     &driver->chem_engine,
                     &driver->chem_sizes,
                     &chem_engine_functionality,
                     &driver->chem_status);
  if (driver->chem_status.error != 0) 
  {
    alquimia_error("TransportDriver_New: %s", driver->chem_status.message);
    return NULL;
  }

  // If you want multiple copies of the chemistry engine with
  // OpenMP, verify: chem_data.functionality.thread_safe == true,
  // then create the appropriate number of chem status and data
  // objects.

  // Allocate memory for the chemistry data.
  AllocateAlquimiaProblemMetaData(&driver->chem_sizes, &driver->chem_metadata);
  driver->chem_properties = malloc(sizeof(AlquimiaProperties) * driver->num_cells);
  driver->chem_state = malloc(sizeof(AlquimiaState) * driver->num_cells);
  driver->chem_aux_data = malloc(sizeof(AlquimiaAuxiliaryData) * driver->num_cells);
  driver->chem_aux_output = malloc(sizeof(AlquimiaAuxiliaryOutputData) * driver->num_cells);
  for (int i = 0; i < driver->num_cells; ++i)
  {
    AllocateAlquimiaState(&driver->chem_sizes, &driver->chem_state[i]);
    AllocateAlquimiaProperties(&driver->chem_sizes, &driver->chem_properties[i]);
    AllocateAlquimiaAuxiliaryData(&driver->chem_sizes, &driver->chem_aux_data[i]);
    AllocateAlquimiaAuxiliaryOutputData(&driver->chem_sizes, &driver->chem_aux_output[i]);
  }

  // Metadata.
  driver->chem.GetProblemMetaData(&driver->chem_engine, 
                                  &driver->chem_metadata, 
                                  &driver->chem_status);
  if (driver->chem_status.error != 0)
  {
    alquimia_error("TransportDriver_New: %s", driver->chem_status.message);
    return NULL;
  }

  // Initial condition.
  AllocateAlquimiaGeochemicalCondition(strlen(input->ic_name), 0, 0, &driver->chem_ic);
  strcpy(driver->chem_ic.name, input->ic_name);

  // Boundary conditions.
  if (input->left_bc_name != NULL)
  {
    AllocateAlquimiaGeochemicalCondition(strlen(input->left_bc_name), 0, 0, &driver->chem_left_bc);
    strcpy(driver->chem_left_bc.name, input->left_bc_name);
  }
  AllocateAlquimiaState(&driver->chem_sizes, &driver->chem_left_state);
  AllocateAlquimiaAuxiliaryData(&driver->chem_sizes, &driver->chem_left_aux_data);
  if (input->right_bc_name != NULL)
  {
    AllocateAlquimiaGeochemicalCondition(strlen(input->right_bc_name), 0, 0, &driver->chem_right_bc);
    strcpy(driver->chem_right_bc.name, input->right_bc_name);
  }
  AllocateAlquimiaState(&driver->chem_sizes, &driver->chem_right_state);
  AllocateAlquimiaAuxiliaryData(&driver->chem_sizes, &driver->chem_right_aux_data);

  // Copy the miscellaneous chemistry state information in.
  // NOTE: For now, we only allow one of each of these reactions.
  for (int i = 0; i < driver->num_cells; ++i)
  {
    for (int j = 0; j < driver->chem_state[i].cation_exchange_capacity.size; ++j)
      driver->chem_state[i].cation_exchange_capacity.data[j] = input->cation_exchange_capacity;
    for (int j = 0; j < driver->chem_state[i].surface_site_density.size; ++j)
      driver->chem_state[i].surface_site_density.data[j] = input->surface_site_density;
  }
  for (int j = 0; j < driver->chem_left_state.cation_exchange_capacity.size; ++j)
    driver->chem_left_state.cation_exchange_capacity.data[j] = input->cation_exchange_capacity;
  for (int j = 0; j < driver->chem_left_state.surface_site_density.size; ++j)
    driver->chem_left_state.surface_site_density.data[j] = input->surface_site_density;
  for (int j = 0; j < driver->chem_right_state.cation_exchange_capacity.size; ++j)
    driver->chem_right_state.cation_exchange_capacity.data[j] = input->cation_exchange_capacity;
  for (int j = 0; j < driver->chem_right_state.surface_site_density.size; ++j)
    driver->chem_right_state.surface_site_density.data[j] = input->surface_site_density;

  // Bookkeeping.
  AllocateAlquimiaState(&driver->chem_sizes, &driver->advected_chem_state);
  AllocateAlquimiaAuxiliaryData(&driver->chem_sizes, &driver->advected_chem_aux_data);
  driver->advective_fluxes = malloc(sizeof(double) * driver->chem_sizes.num_primary * (driver->num_cells + 1));

  return driver;
}