def write_physical(output_dir, solver_name, n_dust): source_file = output_dir + 'Abstract' + solver_name + '_ADERDG.h' f = open(source_file, "r") lines = f.readlines() f.close() remove_function_body(lines, 'isPhysicallyAdmissible') body = [' // Check if all quantities are finite\n'] for i in range(0, 4 + 4 * n_dust): body.append( ' if (!std::isfinite(localDMPObservablesMin[{}])) return false;\n' .format(i)) body.append( ' if (!std::isfinite(localDMPObservablesMax[{}])) return false;\n' .format(i)) body.append('\n // Check for positive densities\n') for i in range(0, n_dust + 1): body.append( ' if (localDMPObservablesMin[{}] <= 0.0) return false;\n'.format( 4 * i)) body.append(' return true;\n') add_function_body(lines, 'isPhysicallyAdmissible', body) # Write to file f = open(source_file, "w") f.writelines(lines) f.close()
def write_plotter_gas_velocity(lines): remove_function_body(lines, 'mapQuantities') body = [ ' const int writtenUnknowns = 3;\n', ' for (int i=0; i<writtenUnknowns; i++){\n', ' outputQuantities[i] = Q[i+1];\n', ' }\n' ] add_function_body(lines, 'mapQuantities', body)
def write_plotter_dust_velocity(lines, n): remove_function_body(lines, 'mapQuantities') body = [ ' const int writtenUnknowns = 3;\n', ' for (int i=0; i<writtenUnknowns; i++){\n', ' outputQuantities[i] = Q[i+1 + 4*{}];\n'.format(n + 1), ' }\n' ] add_function_body(lines, 'mapQuantities', body)
def write_outflow_boundary(lines, n_vars, solver): # Remove current function body remove_function_body(lines, 'boundaryValues') periodic = [' // Outflow boundaries, unimportant if periodic\n'] if (solver == 'ADER-DG'): for n in range(0, n_vars): periodic.extend([' stateOut[{}] = stateIn[{}];\n'.format(n, n)]) for n in range(0, n_vars): periodic.extend([' fluxOut[{}] = fluxIn[{}];\n'.format(n, n)]) if (solver == 'Finite-Volumes'): for n in range(0, n_vars): periodic.extend( [' stateOutside[{}] = stateInside[{}];\n'.format(n, n)]) add_function_body(lines, 'boundaryValues', periodic)
def write_periodic_functions(n_vars, order, offset, size, output_dir, solver_name, n_ghost): fname = output_dir + solver_name + '.cpp' f = open(fname, "r") lines = f.readlines() f.close() # Return if function already modified matches = [match for match in lines if "int n_cell_x = (int)" in match] if len(matches) > 0: return remove_function_body(lines, '::PlotPeriodic') body = \ [' //std::cout << "PLOT PERIODIC " << pos[0] << " " << pos[1] << std::endl;\n', ' // Fill a boundary array for setting periodic boundaries in 2D, non-AMR runs.\n', ' // If mesh = nx times ny, the first nx entries correspond to the bottom boundary.\n', ' // The second nx entries correspond to the top boundary.\n', ' // The next ny entries correspond to the left boundary.\n', ' // The next ny entries correspont to the right boundary.\n', '\n', ' // Hack: number of cells in x and y\n', ' int n_cell_x = (int) round({}/sizeOfPatch[0]);\n'.format(size[0]), ' int n_cell_y = (int) round({}/sizeOfPatch[1]);\n'.format(size[1]), '\n', ' // Make sure vector is of the correct size, and set elements to zero.\n', ' // Note that this should happen only the first time this function is called.\n', ' int n_bound_cells = 2*{}*(n_cell_x + n_cell_y);\n'.format(n_ghost), ' int n_send_per_cell = {};\n'.format(n_vars*(order+1)*(order+1)), ' if (boundaryVector_local.size() != n_send_per_cell*n_bound_cells) {\n', ' boundaryVector_local.resize(n_send_per_cell*n_bound_cells);\n', ' std::fill(boundaryVector_local.begin(), boundaryVector_local.end(), 0.0);\n', ' }\n', '\n', ' // Number of cells to left and bottom\n', ' int cell_x = (int) ((offsetOfPatch[0] + 0.5*sizeOfPatch[0])/sizeOfPatch[0]);\n', ' int cell_y = (int) ((offsetOfPatch[1] + 0.5*sizeOfPatch[1])/sizeOfPatch[1]);\n', '\n', ' int indx = -1;\n', '\n', ' for (int ng = 1; ng < {}; ng++) {{\n'.format(n_ghost + 1), ' if (cell_y == ng + {}) {{\n'.format(n_ghost - 1), ' indx = cell_x;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' boundaryVector_local[arr_index + n] = Q[n];\n', ' }\n', ' if (cell_y == n_cell_y - {} - ng) {{\n'.format(n_ghost), ' indx = n_cell_x + cell_x;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' boundaryVector_local[arr_index + n] = Q[n];\n', ' }\n', ' if (cell_x == ng + {}) {{\n'.format(n_ghost - 1), ' indx = 2*n_cell_x + cell_y;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' boundaryVector_local[arr_index + n] = Q[n];\n', ' }\n', ' if (cell_x == n_cell_x - {} - ng) {{\n'.format(n_ghost), ' indx = 2*n_cell_x + n_cell_y + cell_y;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' boundaryVector_local[arr_index + n] = Q[n];\n', ' }\n', ' }\n'] add_function_body(lines, '::PlotPeriodic', body) remove_function_body(lines, '::SendPeriodic') body = \ [' //std::cout << "SENDING PERIODIC" << std::endl;\n', '#ifdef Parallel\n', ' // Should only happen the first time of call\n', ' if (boundaryVector.size() == 0) {\n', ' if (tarch::parallel::Node::getInstance().getNumberOfNodes() > 1) {\n', ' // Main rank does not know the boundary size\n', ' int s_loc = boundaryVector_local.size();\n', ' int s_max = 0;\n', ' MPI_Reduce(&s_loc, &s_max, 1, MPI_INT, MPI_MAX, 0,\n', ' tarch::parallel::Node::getInstance().getCommunicator());\n', ' // Set correct size so we can use Allreduce\n', ' if (tarch::parallel::Node::getInstance().isGlobalMaster()) {\n', ' boundaryVector_local.resize(s_max);\n', ' std::fill(boundaryVector_local.begin(), boundaryVector_local.end(), 0.0);\n', ' boundaryVector.resize(s_max);\n', ' } else {\n', ' boundaryVector.resize(boundaryVector_local.size());\n', ' }\n', ' } else {\n', ' boundaryVector.resize(boundaryVector_local.size());\n', ' }\n', ' }\n', ' //std::cout << "Allreduce with rank " << tarch::parallel::Node::getInstance().getRank() << " and communicator " << tarch::parallel::Node::getInstance().getCommunicator() << std::endl;\n', ' MPI_Allreduce(&(boundaryVector_local[0]),\n', ' &(boundaryVector[0]),\n', ' boundaryVector_local.size(),\n', ' MPI_DOUBLE,\n', ' MPI_SUM,\n', ' tarch::parallel::Node::getInstance().getCommunicator());\n', '#else\n', ' boundaryVector = boundaryVector_local;\n', '#endif\n'] add_function_body(lines, '::SendPeriodic', body) remove_function_body(lines, '::AdjustPeriodic') body = \ [' //std::cout << "ADJUSTPERIODIC " << pos[0] << " " << pos[1] << std::endl;\n', ' // Hack: number of cells in x and y\n', ' int n_cell_x = (int) round({}/sizeOfPatch[0]);\n'.format(size[0]), ' int n_cell_y = (int) round({}/sizeOfPatch[1]);\n'.format(size[1]), '\n', ' // Number of cells to left and bottom\n', ' int cell_x = (int) ((offsetOfPatch[0] + 0.5*sizeOfPatch[0])/sizeOfPatch[0]);\n', ' int cell_y = (int) ((offsetOfPatch[1] + 0.5*sizeOfPatch[1])/sizeOfPatch[1]);\n', '\n', ' int n_send_per_cell = {};\n'.format(n_vars*(order+1)*(order+1)), ' int indx = -1;\n', '\n', ' for (int ng = 1; ng < {}; ng++) {{\n'.format(n_ghost + 1), ' if (cell_y == n_cell_y - {} + ng - 1) {{\n'.format(n_ghost), ' indx = cell_x;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' Q[n] = boundaryVector[arr_index + n];\n', ' }\n', ' if (cell_y == {} - ng) {{\n'.format(n_ghost), ' indx = n_cell_x + cell_x;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' Q[n] = boundaryVector[arr_index + n];\n', ' }\n', ' if (cell_x == n_cell_x - {} + ng - 1) {{\n'.format(n_ghost), ' indx = 2*n_cell_x + cell_y;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' Q[n] = boundaryVector[arr_index + n];\n', ' }\n', ' if (cell_x == {} - ng) {{\n'.format(n_ghost), ' indx = 2*n_cell_x + n_cell_y + cell_y;\n', ' int arr_index = 2*(n_cell_x + n_cell_y)*n_send_per_cell*(ng - 1) + n_send_per_cell*indx + ({}*pos[1] + pos[0])*{};\n'.format(order + 1, n_vars), ' for (int n = 0; n < {}; n++)\n'.format(n_vars), ' Q[n] = boundaryVector[arr_index + n];\n', ' }\n', ' }\n\n' ' // Return 1 if state adjusted, zero otherwise\n', ' if (indx == -1) return 0;\n', ' return 1;\n' ] add_function_body(lines, '::AdjustPeriodic', body) f = open(fname, "w") f.writelines(lines) f.close()
def write_source(lines, n_dust, q, Stokes, weights, eta): remove_function_body(lines, 'algebraicSource') source = [\ ' // Gas source terms\n', ' S[0] = 0.0;\n', ' S[1] = 2*Q[0]*{} + 2*Q[3];\n'.format(eta), ' S[2] = 0.0;\n', ' S[3] = {}*Q[1];\n'.format(q - 2)] for n in range(0, n_dust): source.extend([\ ' // Source terms for St = {}\n'.format(Stokes[n]), ' S[{}] = 0.0;\n'.format(4*n + 4), ' S[{}] = 2*Q[{}] - (Q[{}] - Q[{}]*Q[1]/Q[0])/{};\n'.format(4*n + 5, 4*n + 7, 4*n + 5, 4*n + 4, Stokes[n]), ' S[{}] = - (Q[{}] - Q[{}]*Q[2]/Q[0])/{};\n'.format(4*n + 6, 4*n + 6, 4*n + 4, Stokes[n]), ' S[{}] = {}*Q[{}] - (Q[{}] - Q[{}]*Q[3]/Q[0])/{};\n'.format(4*n + 7, q - 2, 4*n + 5, 4*n + 7, 4*n + 4, Stokes[n])]) for n in range(0, n_dust): source.extend([\ ' // Gas backreaction for St = {}\n'.format(Stokes[n]), ' S[1] += {}*(Q[{}] -Q[{}]*Q[1]/Q[0])/{};\n'.format(weights[n], 4*n + 5, 4*n + 4, Stokes[n]), ' S[2] += {}*(Q[{}] -Q[{}]*Q[2]/Q[0])/{};\n'.format(weights[n], 4*n + 6, 4*n + 4, Stokes[n]), ' S[3] += {}*(Q[{}] -Q[{}]*Q[3]/Q[0])/{};\n'.format(weights[n], 4*n + 7, 4*n + 4, Stokes[n])]) add_function_body(lines, 'algebraicSource', source) return for i in range(0, len(lines)): # Source x: eta + Coriolis lines[i] = replace_with_indent( lines[i], 'S[1] = ', 'S[1] = 2*Q[0]*{} + 2*Q[3];\n'.format(eta)) # Source y: Coriolis lines[i] = replace_with_indent(lines[i], 'S[3] = ', 'S[3] = {}*Q[1];\n'.format(q - 2)) for n in range(0, n_dust): # Source x: Coriolis + drag lines[i] = replace_with_indent( lines[i], 'S[{}] = '.format(4 * n + 5), 'S[{}] = 2*Q[{}] - (Q[{}] - Q[{}]*Q[1]/Q[0])/{};\n'.format( 4 * n + 5, 4 * n + 7, 4 * n + 5, 4 * n + 4, Stokes[n])) # Source z: drag lines[i] = replace_with_indent( lines[i], 'S[{}] = '.format(4 * n + 6), 'S[{}] = - (Q[{}] - Q[{}]*Q[2]/Q[0])/{};\n'.format( 4 * n + 6, 4 * n + 6, 4 * n + 4, Stokes[n])) # Source y: Coriolis + drag lines[i] = replace_with_indent( lines[i], 'S[{}] = '.format(4 * n + 7), 'S[{}] = {}*Q[{}] - (Q[{}] - Q[{}]*Q[3]/Q[0])/{};\n'.format( 4 * n + 7, q - 2, 4 * n + 5, 4 * n + 7, 4 * n + 4, Stokes[n])) gas_x_drag = [] gas_y_drag = [] gas_z_drag = [] for n in range(0, n_dust): gas_x_drag.append(' S[1] += {}*(Q[{}] -Q[{}]*Q[1]/Q[0])/{};\n'.format( weights[n], 4 * n + 5, 4 * n + 4, Stokes[n])) gas_z_drag.append(' S[2] += {}*(Q[{}] -Q[{}]*Q[2]/Q[0])/{};\n'.format( weights[n], 4 * n + 6, 4 * n + 4, Stokes[n])) gas_y_drag.append(' S[3] += {}*(Q[{}] -Q[{}]*Q[3]/Q[0])/{};\n'.format( weights[n], 4 * n + 7, 4 * n + 4, Stokes[n])) for i in range(0, len(lines)): if (lines[i].find('S[1] = ') != -1): lines[i + 1:i + 1] = gas_x_drag for i in range(0, len(lines)): if (lines[i].find('S[2] = ') != -1): lines[i + 1:i + 1] = gas_z_drag for i in range(0, len(lines)): if (lines[i].find('S[3] = ') != -1): lines[i + 1:i + 1] = gas_y_drag
def allow_periodic(repo_dir): ''' Modify ExaHyPE core to allow periodic boundaries on a regular mesh ''' ########################################################################## # STEP 1: We need two extra adapters: PlotPeriodic (from mesh to boundary # array) and AdjustPeriodic (from boundary array to mesh). The relevant # cpp and h files are copied from the cpp directory of the main repo. Here # we modify the code to be able to use these adapters. ########################################################################## # Add adapter names to RepositoryState.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/records/RepositoryState.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): lines[i] = replace_with_indent(lines[i], 'NumberOfAdapters = 21', 'WriteCheckpoint = 0, ReadCheckpoint = 1, Terminate = 2, RunOnAllNodes = 3, UseAdapterUniformRefinement = 4, UseAdapterMeshRefinement = 5, UseAdapterMeshRefinementAndPlotTree = 6, UseAdapterFinaliseMeshRefinement = 7, UseAdapterFinaliseMeshRefinementOrLocalRollback = 8, UseAdapterInitialPrediction = 9, UseAdapterFusedTimeStep = 10, UseAdapterPredictionRerun = 11, UseAdapterBroadcast = 12, UseAdapterBroadcastAndDropNeighbourMessages = 13, UseAdapterRefinementStatusSpreading = 14, UseAdapterPredictionOrLocalRecomputation = 15, UseAdapterMergeNeighbours = 16, UseAdapterUpdateAndReduce = 17, UseAdapterPrediction = 18, UseAdapterCorrection = 19, UseAdapterAdjustPeriodic = 20, UseAdapterPlotPeriodic = 21, UseAdapterEmpty = 22, NumberOfAdapters = 23\n') f = open(fname, "w") f.writelines(lines) f.close() # Add adapter names to RepositoryState.cpp fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/records/RepositoryState.cpp' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('case UseAdapterCorrection: return "UseAdapterCorrection";') != -1): lines[i+1:i+1] = [' case UseAdapterAdjustPeriodic: return "UseAdapterAdjustPeriodic";\n', ' case UseAdapterPlotPeriodic: return "UseAdapterPlotPeriodic";\n'] lines[i] = replace_with_indent(lines[i], 'NumberOfAdapters=21', 'return "Action(WriteCheckpoint=0,ReadCheckpoint=1,Terminate=2,RunOnAllNodes=3,UseAdapterUniformRefinement=4,UseAdapterMeshRefinement=5,UseAdapterMeshRefinementAndPlotTree=6,UseAdapterFinaliseMeshRefinement=7,UseAdapterFinaliseMeshRefinementOrLocalRollback=8,UseAdapterInitialPrediction=9,UseAdapterFusedTimeStep=10,UseAdapterPredictionRerun=11,UseAdapterBroadcast=12,UseAdapterBroadcastAndDropNeighbourMessages=13,UseAdapterRefinementStatusSpreading=14,UseAdapterPredictionOrLocalRecomputation=15,UseAdapterMergeNeighbours=16,UseAdapterUpdateAndReduce=17,UseAdapterPrediction=18,UseAdapterCorrection=19,UseAdapterAdjustPeriodic=20,UseAdapterPlotPeriodic=21,UseAdapterEmpty=22,NumberOfAdapters=23)";\n') f = open(fname, "w") f.writelines(lines) f.close() # Add switch functions to Repository.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/repositories/Repository.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('virtual void switchToCorrection() = 0;') != -1): lines[i+1:i+1] = [' virtual void switchToAdjustPeriodic() = 0;\n', ' virtual void switchToPlotPeriodic() = 0;\n'] if (lines[i].find('virtual bool isActiveAdapterCorrection() const = 0;') != -1): lines[i+1:i+1] = [' virtual bool isActiveAdapterAdjustPeriodic() const = 0;\n', ' virtual bool isActiveAdapterPlotPeriodic() const = 0;\n'] f = open(fname, "w") f.writelines(lines) f.close() # Add functions to RepositorySTDStack.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/repositories/RepositorySTDStack.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): # Include the new adapter headers if (lines[i].find('#include "exahype/adapters/Correction.h"') != -1): lines[i+1:i+1] = [' #include "exahype/adapters/AdjustPeriodic.h"\n', ' #include "exahype/adapters/PlotPeriodic.h"\n'] # Declare new grids if (lines[i].find('peano::grid::Grid<exahype::Vertex,exahype::Cell,exahype::State,VertexStack,CellStack,exahype::adapters::Correction> _gridWithCorrection;') != -1): lines[i+1:i+1] = [' peano::grid::Grid<exahype::Vertex,exahype::Cell,exahype::State,VertexStack,CellStack,exahype::adapters::AdjustPeriodic> _gridWithAdjustPeriodic;\n', ' peano::grid::Grid<exahype::Vertex,exahype::Cell,exahype::State,VertexStack,CellStack,exahype::adapters::PlotPeriodic> _gridWithPlotPeriodic;\n'] # Declare new switch functions if (lines[i].find('virtual void switchToCorrection();') != -1): lines[i+1:i+1] = [' virtual void switchToAdjustPeriodic();\n', ' virtual void switchToPlotPeriodic();\n'] # Declare new IsActive functions if (lines[i].find('virtual bool isActiveAdapterCorrection() const;') != -1): lines[i+1:i+1] = [' virtual bool isActiveAdapterAdjustPeriodic() const;\n', ' virtual bool isActiveAdapterPlotPeriodic() const;\n'] # Declare new time measurement functions if (lines[i].find('tarch::timing::Measurement _measureCorrectionCPUTime;') != -1): lines[i+1:i+1] = [' tarch::timing::Measurement _measureAdjustPeriodicCPUTime;\n', ' tarch::timing::Measurement _measurePlotPeriodicCPUTime;\n'] if (lines[i].find('tarch::timing::Measurement _measureCorrectionCalendarTime;') != -1): lines[i+1:i+1] = [' tarch::timing::Measurement _measureAdjustPeriodicCalendarTime;\n', ' tarch::timing::Measurement _measurePlotPeriodicCalendarTime;\n'] f = open(fname, "w") f.writelines(lines) f.close() # Add functions to RepositorySTDStack.cpp fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/repositories/RepositorySTDStack.cpp' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('_gridWithCorrection(_vertexStack,_cellStack,_geometry,_solverState,domainSize,computationalDomainOffset,_regularGridContainer,_traversalOrderOnTopLevel),') != -1): lines[i+1:i+1] = [' _gridWithAdjustPeriodic(_vertexStack,_cellStack,_geometry,_solverState,domainSize,computationalDomainOffset,_regularGridContainer,_traversalOrderOnTopLevel),\n', ' _gridWithPlotPeriodic(_vertexStack,_cellStack,_geometry,_solverState,domainSize,computationalDomainOffset,_regularGridContainer,_traversalOrderOnTopLevel),\n'] if (lines[i].find('_gridWithCorrection(_vertexStack,_cellStack,_geometry,_solverState,_regularGridContainer,_traversalOrderOnTopLevel),') != -1): lines[i+1:i+1] = [' _gridWithAdjustPeriodic(_vertexStack,_cellStack,_geometry,_solverState,_regularGridContainer,_traversalOrderOnTopLevel),\n',' _gridWithPlotPeriodic(_vertexStack,_cellStack,_geometry,_solverState,_regularGridContainer,_traversalOrderOnTopLevel),\n'] if (lines[i].find('_gridWithCorrection.restart') != -1): lines[i+1:i+1] = [' _gridWithAdjustPeriodic.restart(domainSize,domainOffset,domainLevel, positionOfCentralElementWithRespectToCoarserRemoteLevel);\n', ' _gridWithPlotPeriodic.restart(domainSize,domainOffset,domainLevel, positionOfCentralElementWithRespectToCoarserRemoteLevel);\n'] if (lines[i].find('_gridWithCorrection.terminate') != -1): lines[i+1:i+1] = [' _gridWithAdjustPeriodic.terminate();\n', ' _gridWithPlotPeriodic.terminate();\n'] if (lines[i].find('case exahype::records::RepositoryState::UseAdapterCorrection:') != -1): lines[i+1:i+1] = [' case exahype::records::RepositoryState::UseAdapterAdjustPeriodic: watch.startTimer(); _gridWithAdjustPeriodic.iterate(); watch.stopTimer(); _measureAdjustPeriodicCPUTime.setValue( watch.getCPUTime() ); _measureAdjustPeriodicCalendarTime.setValue( watch.getCalendarTime() ); break;\n', ' case exahype::records::RepositoryState::UseAdapterPlotPeriodic: watch.startTimer(); _gridWithPlotPeriodic.iterate(); watch.stopTimer(); _measurePlotPeriodicCPUTime.setValue( watch.getCPUTime() ); _measurePlotPeriodicCalendarTime.setValue( watch.getCalendarTime() ); break;\n'] if (lines[i].find('void exahype::repositories::RepositorySTDStack::switchToCorrection() { _repositoryState.setAction(exahype::records::RepositoryState::UseAdapterCorrection); }') != -1): lines[i+1:i+1] = [' void exahype::repositories::RepositorySTDStack::switchToAdjustPeriodic() { _repositoryState.setAction(exahype::records::RepositoryState::UseAdapterAdjustPeriodic); }\n', ' void exahype::repositories::RepositorySTDStack::switchToPlotPeriodic() { _repositoryState.setAction(exahype::records::RepositoryState::UseAdapterPlotPeriodic); }\n'] if (lines[i].find('bool exahype::repositories::RepositorySTDStack::isActiveAdapterCorrection() const { return _repositoryState.getAction() == exahype::records::RepositoryState::UseAdapterCorrection; }') != -1): lines[i+1:i+1] = [' bool exahype::repositories::RepositorySTDStack::isActiveAdapterAdjustPeriodic() const { return _repositoryState.getAction() == exahype::records::RepositoryState::UseAdapterAdjustPeriodic; }\n', ' bool exahype::repositories::RepositorySTDStack::isActiveAdapterPlotPeriodic() const { return _repositoryState.getAction() == exahype::records::RepositoryState::UseAdapterPlotPeriodic; }\n'] # Add logging functions for i in range(0, len(lines)): if (lines[i].find('if (logAllAdapters || _measureCorrectionCPUTime.getNumberOfMeasurements()>0) logInfo( "logIterationStatistics()", "| Correction \t | " << _measureCorrectionCPUTime.getNumberOfMeasurements() << " \t | " << _measureCorrectionCPUTime.getAccumulatedValue() << " \t | " << _measureCorrectionCPUTime.getValue() << " \t | " << _measureCorrectionCalendarTime.getAccumulatedValue() << " \t | " << _measureCorrectionCalendarTime.getValue() << " \t | " << _measureCorrectionCPUTime.toString() << " \t | " << _measureCorrectionCalendarTime.toString() );') != -1): lines[i+1:i+1] = [' if (logAllAdapters || _measureAdjustPeriodicCPUTime.getNumberOfMeasurements()>0) logInfo( "logIterationStatistics()", "| AdjustPeriodic \t | " << _measureAdjustPeriodicCPUTime.getNumberOfMeasurements() << " \t | " << _measureAdjustPeriodicCPUTime.getAccumulatedValue() << " \t | " << _measureAdjustPeriodicCPUTime.getValue() << " \t | " << _measureAdjustPeriodicCalendarTime.getAccumulatedValue() << " \t | " << _measureAdjustPeriodicCalendarTime.getValue() << " \t | " << _measureAdjustPeriodicCPUTime.toString() << " \t | " << _measureAdjustPeriodicCalendarTime.toString() );\n', ' if (logAllAdapters || _measurePlotPeriodicCPUTime.getNumberOfMeasurements()>0) logInfo( "logIterationStatistics()", "| PlotPeriodic \t | " << _measurePlotPeriodicCPUTime.getNumberOfMeasurements() << " \t | " << _measurePlotPeriodicCPUTime.getAccumulatedValue() << " \t | " << _measurePlotPeriodicCPUTime.getValue() << " \t | " << _measurePlotPeriodicCalendarTime.getAccumulatedValue() << " \t | " << _measurePlotPeriodicCalendarTime.getValue() << " \t | " << _measurePlotPeriodicCPUTime.toString() << " \t | " << _measurePlotPeriodicCalendarTime.toString() );\n'] for i in range(0, len(lines)): if (lines[i].find('_measureCorrectionCPUTime.erase();') != -1): lines[i+1:i+1] = [' _measureAdjustPeriodicCPUTime.erase();\n', ' _measurePlotPeriodicCPUTime.erase();\n'] for i in range(0, len(lines)): if (lines[i].find('_measureCorrectionCalendarTime.erase();') != -1): lines[i+1:i+1] = [' _measureAdjustPeriodicCalendarTime.erase();\n', ' _measurePlotPeriodicCalendarTime.erase();\n'] f = open(fname, "w") f.writelines(lines) f.close() ########################################################################## # STEP 2: Integrate new adapters into time stepping loop. At the start of # a time step, that is, after the correction update: First use the # 'plotting' adapter to get the boundary values into and array, followed # by the 'adjusting' adapter to get the values on the periodic boundaries # on the mesh. ########################################################################## # Modify time stepping fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/runners/Runner.cpp' f = open(fname, "r") lines = f.readlines() f.close() body = remove_function_body(lines, '::runOneTimeStepWithThreeSeparateAlgorithmicSteps') for i in range(0, len(body)): if (body[i].find('repository.switchToPrediction(); // Cell onto faces') != -1): body[i:i] = [' repository.switchToPlotPeriodic();\n', ' repository.iterate(1, communicatePeanoVertices);\n', ' repository.switchToAdjustPeriodic();\n', ' repository.iterate(1, communicatePeanoVertices);\n', '\n'] add_function_body(lines, '::runOneTimeStepWithThreeSeparateAlgorithmicSteps', body) f = open(fname, "w") f.writelines(lines) f.close() ########################################################################## # STEP 3: Declare and define the functions performing the 'plotting' and # 'adjusting'. For 'adjusting' we rely on the existing adjustSolution # functions. For 'plotting', the final PlotPeriodic function will have to # be defined in the user abstract class. ########################################################################## ################################# # First deal with ADER-DG solver ################################# fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/ADERDGSolver.cpp' f = open(fname, "r") lines = f.readlines() f.close() lines[len(lines):len(lines)] = \ ['\n', 'int exahype::solvers::ADERDGSolver::AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) {\n', ' int ret = 0;\n', ' const int element = cellInfo.indexOfADERDGCellDescription(solverNumber);\n', ' if ( element != NotFound ) {\n', ' CellDescription& cellDescription = cellInfo._ADERDGCellDescriptions[element];\n', ' if ( cellDescription.getType()==CellDescription::Type::Leaf ) {\n', ' double* solverSolution =\n', ' static_cast<double*>(cellDescription.getSolution());\n', '\n', ' const int order = getNodesPerCoordinateAxis() - 1;\n', ' const int basisX = order + 1;\n', ' const int basisY = order + 1;\n', ' const int basisZ = (DIMENSIONS == 3 ? order : 0 ) + 1;\n', ' kernels::index idx_u(basisZ, basisY, basisX, getNumberOfVariables());\n', '\n', ' // Call the solver-defined AdjustPeriodic function\n', ' dfor(i, order + 1) {\n', ' ret = AdjustPeriodic(\n', ' cellDescription.getOffset(),\n', ' cellDescription.getSize(),\n', ' i,\n', ' solverSolution + idx_u(DIMENSIONS == 3 ? i(2) : 0, i(1), i(0), 0));\n', ' }\n', ' }\n', ' }\n', ' return ret;\n', '}\n', '\n', 'void exahype::solvers::ADERDGSolver::PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) {\n', ' const int element = cellInfo.indexOfADERDGCellDescription(solverNumber);\n', ' if ( element != NotFound ) {\n', ' CellDescription& cellDescription = cellInfo._ADERDGCellDescriptions[element];\n', ' if ( cellDescription.getType()==CellDescription::Type::Leaf ) {\n', ' double* solverSolution =\n', ' static_cast<double*>(cellDescription.getSolution());\n', '\n', ' const int order = getNodesPerCoordinateAxis() - 1;\n', ' const int basisX = order + 1;\n', ' const int basisY = order + 1;\n', ' const int basisZ = (DIMENSIONS == 3 ? order : 0 ) + 1;\n', ' kernels::index idx_u(basisZ, basisY, basisX, getNumberOfVariables());\n', '\n', ' // Call the solver-defined PlotPeriodic function\n', ' dfor(i, order + 1) {\n', ' PlotPeriodic(\n', ' cellDescription.getOffset(),\n', ' cellDescription.getSize(),\n', ' i,\n', ' solverSolution + idx_u(DIMENSIONS == 3 ? i(2) : 0, i(1), i(0), 0));\n', ' }\n', ' }\n', ' }\n', '}\n', '\n', 'void exahype::solvers::ADERDGSolver::FinishPeriodic() {\n', ' SendPeriodic();\n', '}\n', '\n', ] f = open(fname, "w") f.writelines(lines) f.close() # Add functions to ADERDGsolver.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/ADERDGSolver.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('void updateOrRestrict(') != -1): lines[i:i] = [' void PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) final override;\n', ' int AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) final override;\n', ' virtual void PlotPeriodic(\n', ' const tarch::la::Vector<DIMENSIONS, double>& offsetOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, double>& sizeOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, int>& pos,\n', ' double* const Q) = 0;\n', ' virtual int AdjustPeriodic(\n', ' const tarch::la::Vector<DIMENSIONS, double>& offsetOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, double>& sizeOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, int>& pos,\n', ' double* Q) = 0;\n', ' void FinishPeriodic() final override;\n', ' virtual void SendPeriodic() = 0;\n', '\n'] break; f = open(fname, "w") f.writelines(lines) f.close() ################################# # Next: FV solver ################################# fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/FiniteVolumesSolver.cpp' f = open(fname, "r") lines = f.readlines() f.close() lines[len(lines):len(lines)] = \ ['\n', 'int exahype::solvers::FiniteVolumesSolver::AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) {\n', ' int ret = 0;\n', ' const int element = cellInfo.indexOfFiniteVolumesCellDescription(solverNumber);\n', ' if ( element != NotFound ) {\n', ' CellDescription& cellDescription = cellInfo._FiniteVolumesCellDescriptions[element];\n', ' if ( cellDescription.getType()==CellDescription::Type::Leaf ) {\n', ' double* solverSolution =\n', ' static_cast<double*>(cellDescription.getSolution());\n', '\n', ' kernels::idx3 idx(_nodesPerCoordinateAxis+2*_ghostLayerWidth,\n', ' _nodesPerCoordinateAxis+2*_ghostLayerWidth,\n', ' _numberOfVariables+_numberOfParameters);\n', ' for (int i = _ghostLayerWidth; i < _nodesPerCoordinateAxis + _ghostLayerWidth; i++) {\n', ' for (int j = _ghostLayerWidth; j < _nodesPerCoordinateAxis + _ghostLayerWidth; j++) {\n', ' tarch::la::Vector<DIMENSIONS, int> pos(i - _ghostLayerWidth, j - _ghostLayerWidth);\n', ' ret = AdjustPeriodic(\n', ' cellDescription.getOffset(),\n', ' cellDescription.getSize(),\n', ' pos,\n', ' solverSolution + idx(j, i, 0));\n', ' }\n', ' }\n', ' }\n', ' }\n', ' return ret;\n', '}\n', '\n', 'void exahype::solvers::FiniteVolumesSolver::PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) {\n', ' const int element = cellInfo.indexOfFiniteVolumesCellDescription(solverNumber);\n', ' if ( element != NotFound ) {\n', ' CellDescription& cellDescription = cellInfo._FiniteVolumesCellDescriptions[element];\n', ' if ( cellDescription.getType()==CellDescription::Type::Leaf ) {\n', ' double* solverSolution =\n', ' static_cast<double*>(cellDescription.getSolution());\n', '\n', ' kernels::idx3 idx(_nodesPerCoordinateAxis+2*_ghostLayerWidth,\n', ' _nodesPerCoordinateAxis+2*_ghostLayerWidth,\n', ' _numberOfVariables+_numberOfParameters);\n', ' for (int i = _ghostLayerWidth; i < _nodesPerCoordinateAxis + _ghostLayerWidth; i++) {\n', ' for (int j = _ghostLayerWidth; j < _nodesPerCoordinateAxis + _ghostLayerWidth; j++) {\n', ' tarch::la::Vector<DIMENSIONS, int> pos(i - _ghostLayerWidth, j - _ghostLayerWidth);\n', ' // Call the solver-defined PlotPeriodic function\n', ' PlotPeriodic(\n', ' cellDescription.getOffset(),\n', ' cellDescription.getSize(),\n', ' pos,\n', ' solverSolution + idx(j, i, 0));\n', ' }\n', ' }\n', ' }\n', ' }\n', '}\n', '\n', 'void exahype::solvers::FiniteVolumesSolver::FinishPeriodic() {\n', ' SendPeriodic();\n', '}\n', '\n', ] f = open(fname, "w") f.writelines(lines) f.close() # Add functions to FiniteVolumesSolver.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/FiniteVolumesSolver.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('void updateOrRestrict(') != -1): lines[i:i] = [' void PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) final override;\n', ' int AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) final override;\n', ' virtual void PlotPeriodic(\n', ' const tarch::la::Vector<DIMENSIONS, double>& offsetOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, double>& sizeOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, int>& pos,\n', ' double* const Q) = 0;\n', ' virtual int AdjustPeriodic(\n', ' const tarch::la::Vector<DIMENSIONS, double>& offsetOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, double>& sizeOfPatch,\n', ' const tarch::la::Vector<DIMENSIONS, int>& pos,\n', ' double* Q) = 0;\n', ' void FinishPeriodic() final override;\n', ' virtual void SendPeriodic() = 0;\n', '\n'] break; f = open(fname, "w") f.writelines(lines) f.close() ################################# # Finally: limiting scheme ################################# fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/LimitingADERDGSolver.cpp' f = open(fname, "r") lines = f.readlines() f.close() lines[len(lines):len(lines)] = \ ['\n', 'int exahype::solvers::LimitingADERDGSolver::AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) {\n', ' int madeAdjustment = _solver->AdjustPeriodic(solverNumber, cellInfo, usePreviousSolution);\n', ' int madeAdjustmentLimiter = _limiter->AdjustPeriodic(solverNumber, cellInfo, usePreviousSolution);\n', ' if (madeAdjustment) {\n', ' const int solverElement = cellInfo.indexOfADERDGCellDescription(solverNumber);\n', ' if ( solverElement != Solver::NotFound ) {\n', ' determineMinAndMax(solverNumber, cellInfo);\n', #' SolverPatch& solverPatch = cellInfo._ADERDGCellDescriptions[solverElement];\n', #' std::cout << "Adjust Refinement status: " << solverPatch.getRefinementStatus() << " " << _solver->_minRefinementStatusForTroubledCell << std::endl;\n', #' solverPatch.setRefinementStatus(_solver->_minRefinementStatusForTroubledCell);\n', #' const int limiterElement = cellInfo.indexOfFiniteVolumesCellDescription(solverNumber);\n', #' if (limiterElement != Solver::NotFound) {\n', #' LimiterPatch& limiterPatch = getLimiterPatch(solverPatch,cellInfo);\n', #' projectDGSolutionOnFVSpace(solverPatch,limiterPatch);\n', #' }\n', ' }\n', ' }\n', ' return 0;\n', '}\n', '\n', 'void exahype::solvers::LimitingADERDGSolver::PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) {\n', ' _solver->PlotPeriodic(solverNumber, cellInfo, usePreviousSolution);\n', ' _limiter->PlotPeriodic(solverNumber, cellInfo, usePreviousSolution);\n', '}\n', '\n', 'void exahype::solvers::LimitingADERDGSolver::FinishPeriodic() {\n', ' _solver->FinishPeriodic();\n', ' _limiter->FinishPeriodic();\n', '}\n', '\n', ] f = open(fname, "w") f.writelines(lines) f.close() # Add functions to LimitingADERDGsolver.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/LimitingADERDGSolver.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('void updateOrRestrict(') != -1): lines[i:i] = [' void PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) final override;\n', ' int AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) final override;\n', ' void FinishPeriodic() final override;\n', '\n'] break; f = open(fname, "w") f.writelines(lines) f.close() # Add functions to Solver.h fname = repo_dir + 'ExaHyPE-Engine/ExaHyPE/exahype/solvers/Solver.h' f = open(fname, "r") lines = f.readlines() f.close() for i in range(0, len(lines)): if (lines[i].find('* The nonfused update routine.') != -1): lines[i-1:i-1] = \ [' virtual void PlotPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) = 0;\n', ' virtual int AdjustPeriodic(\n', ' const int solverNumber,\n', ' CellInfo& cellInfo,\n', ' bool usePreviousSolution) = 0;\n', ' virtual void FinishPeriodic() = 0;\n', '\n'] break; f = open(fname, "w") f.writelines(lines) f.close()