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); }
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; }