/** * find_rtas_end * @brief Find the ending of a RTAS event. * * @param textstart pointer to starting point of search * @param textend pointer to ending point of search * @return pointer to RTAS event end on success, NULL on failure. */ char * find_rtas_end(char *textstart, char *textend) { if (textstart == NULL) return NULL; if (bad_char_end[0] == -1) setup_bc(RTAS_END, strlen(RTAS_END), bad_char_end); return find_event(RTAS_END, strlen(RTAS_END), textstart, textend - textstart, bad_char_end); }
/** * find_rtas_start * @brief Find the beginning of a RTAS event. * * @param textstart pointer to starting point of search * @param textend pointer to ending point of search * @return pointer to RTAS event start on success, NULL on failure. */ char * find_rtas_start(char *textstart, char *textend) { if (textstart == NULL) return NULL; if (bad_char_start[0] == -1) setup_bc(RTAS_START, strlen(RTAS_START), bad_char_start); return find_event(RTAS_START, strlen(RTAS_START), textstart, textend - textstart, bad_char_start); }
int main(int argc, char *argv[]) { /* See Aztec User's Guide for the variables that follow: */ int proc_config[AZ_PROC_SIZE];/* Processor information. */ int N_update; /* # of unknowns updated on this node */ int *update; /* vector elements updated on this node */ int *data_orgA; /* Array to specify data layout */ int *externalA; /* vector elements needed by this node. */ int *update_indexA; /* ordering of update[] and external[] */ int *extern_indexA; /* locally on this processor. */ int *bindxA; /* Sparse matrix to be solved is stored */ double *valA; /* in these MSR arrays. */ AZ_MATRIX *mat_curl_edge; /* curl operator matrix */ int *data_orgB; /* Array to specify data layout */ int *externalB; /* vector elements needed by this node. */ int *update_indexB; /* ordering of update[] and external[] */ int *extern_indexB; /* locally on this processor. */ int *bindxB; /* Sparse matrix to be solved is stored */ double *valB; /* in these MSR arrays. */ AZ_MATRIX *mat_curl_face; /* curl operator matrix */ int *bc_indx; int n_bc; double *efield; double *bfield; double *epsilon; double *tmp_vec; double *tmp_vec2; int i, nrow, x, y, z; int k, t; long startTime, endTime; int myrank; int vec_len; /* get number of processors and the name of this processor */ #ifdef AZ_MPI MPI_Init(&argc,&argv); AZ_set_proc_config(proc_config, MPI_COMM_WORLD); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); #else myrank = 0; AZ_set_proc_config(proc_config, AZ_NOT_MPI); #endif nrow = ncomp * nx * ny * nz; /* overll number of matrix rows */ // Define partitioning: matrix rows (ascending order) owned by this node // Here it is done automatically, but it can also be specified by hand AZ_read_update(&N_update, &update, proc_config, nrow, 1, AZ_linear); // In the following we set up the matrix for the edge centered curl operator // All the steps are described in detail in the AZTEC manual. // first: allocate space for the first matrix. bindxA = (int *) malloc((N_update*MAX_NZ_ROW+1)*sizeof(int)); valA = (double *) malloc((N_update*MAX_NZ_ROW+1)*sizeof(double)); if (valA == NULL) perror("Error: Not enough space to create matrix"); // Initialize the index for the first off diagonal element bindxA[0] = N_update+1; // Create the matrix row by row. Each processor creates only rows appearing // in update[] (using global col. numbers). for (i = 0; i < N_update; i++) create_curl_matrix_row_edge(update[i], i, valA, bindxA); // convert matrix to a local distributed matrix AZ_transform(proc_config, &externalA, bindxA, valA, update, &update_indexA, &extern_indexA, &data_orgA, N_update, NULL, NULL, NULL, NULL, AZ_MSR_MATRIX); // convert the matrix arrays into a matrix structure, used in the // matrix vector multiplication mat_curl_edge = AZ_matrix_create(data_orgA[AZ_N_internal] + data_orgA[AZ_N_border]); AZ_set_MSR(mat_curl_edge, bindxA, valA, data_orgA, 0, NULL, AZ_LOCAL); // at this point the edge centered curl matrix is completed. // In the following we set up the matrix for the face centered curl operator // All the steps are described in detail in the AZTEC manual. // first: allocate space for the first matrix. bindxB = (int *) malloc((N_update*MAX_NZ_ROW+1)*sizeof(int)); valB = (double *) malloc((N_update*MAX_NZ_ROW+1)*sizeof(double)); if (valB == NULL) perror("Error: Not enough space to create matrix"); // Initialize the index for the first off diagonal element bindxB[0] = N_update+1; // Create the matrix row by row. Each processor creates only rows appearing // in update[] (using global col. numbers). for (i = 0; i < N_update; i++) create_curl_matrix_row_face(update[i], i, valB, bindxB); // convert matrix to a local distributed matrix AZ_transform(proc_config, &externalB, bindxB, valB, update, &update_indexB, &extern_indexB, &data_orgB, N_update, NULL, NULL, NULL, NULL, AZ_MSR_MATRIX); // convert the matrix arrays into a matrix structure, used in the // matrix vector multiplication mat_curl_face = AZ_matrix_create(data_orgB[AZ_N_internal] + data_orgB[AZ_N_border]); AZ_set_MSR(mat_curl_face, bindxB, valB, data_orgB, 0, NULL, AZ_LOCAL); // at this point the face centered curl matrix is completed. // allocate memory for the fields and a temporary vector vec_len = N_update + data_orgA[AZ_N_external]; efield = (double *) malloc(vec_len*sizeof(double)); bfield = (double *) malloc(vec_len*sizeof(double)); epsilon = (double *) malloc(vec_len*sizeof(double)); tmp_vec = (double *) malloc(vec_len*sizeof(double)); tmp_vec2 = (double *) malloc(vec_len*sizeof(double)); // setup the boundary condition. We will get an arry that tells us // which positions need to be updated and where the results needs // to be stored in the E field. setup_bc(update, update_indexB, N_update, &bc_indx, &n_bc); // initialize the field vectors for(k = 0; k < vec_len; k++){ efield[k] = 0.; bfield[k] = 0.; epsilon[k] = 1.; tmp_vec[k] = 0.; } // initialize the dielectric structure. Ugly hard-coded stuff, // needs to be cleaned out... for(y=45; y<55; y++){ for(x = y; x<100; x++) epsilon[compZ + pos_to_row(x, y, 0)] = 0.95; } // reorder the dielectric vector in order to align with the B field AZ_reorder_vec(epsilon, data_orgA, update_indexA, NULL); printf("Begin iteration \n"); // just some timing ... startTime = currentTimeMillis(); // ******************* // begin of the time stepping loop // ******************* for( t = 0; t < nsteps; t++){ // first we do the e field update // convert the B field to the H field for(k = 0 ; k < vec_len; k++) bfield[k] *= epsilon[k]; // setup the initial condition for( k = 0; k < n_bc; k++){ x = bc_indx[4*k]; y = bc_indx[4*k+1]; z = bc_indx[4*k+2]; efield[bc_indx[4*k+3]] = sin((double) y * 5. * 3.14159 / (double) ny) * sin(omega * dt * (double) (t + 1)); } // E field update: // tmp_vec = Curl_Op * bfield // efield = efield + c^2 * dt * tmp_vec AZ_MSR_matvec_mult( bfield, tmp_vec, mat_curl_edge, proc_config); // reorder the result in tmp_vec so that it aligns with the // decomposition of the E field AZ_invorder_vec(tmp_vec, data_orgA, update_indexA, NULL, tmp_vec2); AZ_reorder_vec(tmp_vec2, data_orgB, update_indexB, NULL); // update the efield for(k = 0 ; k < N_update; k++) efield[k] = efield[k] + c2 * tmp_vec2[k] * dt; // bfield update : // tmp_vec = DualCurl_Op * efield // bfield = bfield - tmp_vec * dt AZ_MSR_matvec_mult( efield, tmp_vec, mat_curl_face, proc_config); // reorder the result so that it fits the decomposition of the bfield AZ_invorder_vec(tmp_vec, data_orgB, update_indexB, NULL, tmp_vec2); AZ_reorder_vec(tmp_vec2, data_orgA, update_indexA, NULL); // update the b field for(k = 0; k < N_update; k++) bfield[k] = bfield[k] - tmp_vec2[k] * dt; if(myrank == 0) printf("Taking step %d at time %g\n", t, (double) (currentTimeMillis() - startTime) / 1000.); } // ****************** // end of timestepping loop // ***************** endTime = currentTimeMillis(); printf("After iteration: %g\n", (double)(endTime - startTime) / 1000. ); #if 1 system("rm efield.txt bfield.txt"); // dump filed data: efield AZ_invorder_vec(efield, data_orgB, update_indexB, NULL, tmp_vec); write_file("efield.txt", tmp_vec, N_update); // dump filed data: bfield AZ_invorder_vec(bfield, data_orgA, update_indexA, NULL, tmp_vec); write_file("bfield.txt", tmp_vec, N_update); #endif /* Free allocated memory */ AZ_matrix_destroy( &mat_curl_edge); free((void *) update); free((void *) update_indexA); free((void *) externalA); free((void *) extern_indexA); free((void *) bindxA); free((void *) valA); free((void *) data_orgA); AZ_matrix_destroy( &mat_curl_face); free((void *) externalB); free((void *) extern_indexB); free((void *) bindxB); free((void *) valB); free((void *) data_orgB); free((void *) efield); free((void *) bfield); free((void *) tmp_vec); free((void *) tmp_vec2); #ifdef AZ_MPI MPI_Finalize(); #endif return(1); }