/*---------------------------------------------------------------------------*/ static void solve_sparse_diag_block(int begin, int end, sparse_t *A, double *B, double *x) /*---------------------------------------------------------------------------*/ { int n = end-begin; int i,j,k; int nnz = A->ia[end]-A->ia[begin]; sparse_t *a = sparse_alloc(n, n, nnz); double *b = calloc(n, sizeof *b); int pos = 0; for (i=begin; i<end; ++i) b [i-begin] = B [i]; a->ia[0] = 0; for (i=begin; i<end; ++i) { int I = i-begin; for (k=A->ia[i]; k<A->ia[i+1]; ++k) { j = A->ja[k]-begin; assert(j<end); if (j<0) b[I] -= A->a[k]*x[begin+j]; else /* i==j */ { a->ja[pos] = j; a->a [pos] = A->a[k]; ++pos; } } a->ia[i+1-begin]=pos; } /* sparse_display(a, stderr);fprintf(stderr, "\n"); */ sparse_solve(a, b, x+begin); free(b); sparse_free(a); }
int main(int argc, char* argv[]) { bool hermite_false, hermite_true; int n1, n2, npml, pad1, pad2, ns, nw, nh; float d1, d2, **v, ds, os, dw, ow; double omega; sf_complex ***f, ***srcw, ***recw, ***obs, ***obs_cut; sf_file in, out, source, receiver, record; int uts, mts; char *order; int is, i, j, iw, ih; float ***image, **recloc; sf_init(argc, argv); in = sf_input("in"); out = sf_output("out"); if (!sf_getint("nh",&nh)) nh=0; if (!sf_getint("uts",&uts)) uts=0; //#ifdef _OPENMP // mts = omp_get_max_threads(); //#else mts = 1; //#endif uts = (uts < 1)? mts: uts; hermite_false=false; hermite_true=true; /* Hermite operator */ if (!sf_getint("npml",&npml)) npml=20; /* PML width */ if (NULL == (order = sf_getstring("order"))) order="j"; /* discretization scheme (default optimal 9-point) */ fdprep_order(order); /* read input dimension */ if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input."); if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input."); if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input."); if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input."); v = sf_floatalloc2(n1,n2); sf_floatread(v[0],n1*n2,in); /* PML padding */ pad1 = n1+2*npml; pad2 = n2+2*npml; /* read receiver */ if (NULL == sf_getstring("receiver")) sf_error("Need receiver="); receiver = sf_input("receiver"); recloc=sf_floatalloc2(n1,n2); sf_floatread(recloc[0],n1*n2,receiver); /* read source */ if (NULL == sf_getstring("source")) sf_error("Need source="); source = sf_input("source"); if (!sf_histint(source,"n3",&ns)) sf_error("No ns=."); if (!sf_histfloat(source,"d3",&ds)) ds=d2; if (!sf_histfloat(source,"o3",&os)) os=0.; f = sf_complexalloc3(n1,n2,ns); /* read observed data */ if (NULL == sf_getstring("record")) sf_error("Need record="); record = sf_input("record"); if (!sf_histint(record,"n4",&nw)) sf_error("No nw=."); if (!sf_histfloat(record,"d4",&dw)) sf_error("No dw=."); if (!sf_histfloat(record,"o4",&ow)) sf_error("No ow=."); obs = sf_complexalloc3(n1,n2,ns); obs_cut = sf_complexalloc3(n1,n2,ns); srcw = sf_complexalloc3(n1,n2,ns); recw = sf_complexalloc3(n1,n2,ns); image = sf_floatalloc3(n1,n2,2*nh+1); /* Loop over frequency */ for (iw=0; iw<nw; iw++ ) { omega=(double) 2.*SF_PI*(ow+iw*dw); sf_warning("Calculating frequency %d out of %d for %f HZ.",iw+1,nw,ow+iw*dw); sf_complexread(f[0][0],n1*n2*ns,source); sf_complexread(obs[0][0],n1*n2*ns,record); /* generate adjoint source for reverse time migration */ genadjsrc_rtm(obs, obs_cut, recloc, n1, n2, ns); /* initialize sparse solver */ sparse_init(uts, pad1, pad2); /* factorize matrix, change according to different frequencies and models */ sparse_factor(omega,n1,n2,d1,d2,v,npml,pad1,pad2,uts); for (is=0; is < ns; is++ ) { for (j=0; j < n2; j++ ) { for (i=0; i < n1; i++ ) { srcw[is][j][i]=f[is][j][i]; recw[is][j][i]=obs_cut[is][j][i]; } } } /* sparse solver for source wavefield */ sparse_solve(npml, pad1, pad2, srcw, hermite_false, ns, uts); /* sparse solver for receiver wavefield */ sparse_solve(npml, pad1, pad2, recw, hermite_true, ns, uts); /* imaging condition */ for (ih=-nh; ih < nh+1; ih++ ) { for (j=0; j<n2; j++ ) { for (i=0; i< n1; i++ ) { for (is=0; is < ns; is++ ) { if (j-abs(ih) >= 0 && j+abs(ih) < n2) { image[ih+nh][j][i] += crealf(omega*omega*conjf(srcw[is][j-ih][i])*recw[is][j+ih][i]/(v[j][i]*v[j][i])); } } } } } /* free memory */ sparse_free(uts); } /* end frequency */ sf_putint(out,"n1",n1); sf_putint(out,"n2",n2); sf_putint(out,"n3",2*nh+1); sf_putfloat(out,"d3",d2); sf_putfloat(out,"o3", (float) -nh*d2); sf_floatwrite(image[0][0],n1*n2*(2*nh+1),out); exit(0); }
int main(int argc, char *argv[]) { exit_if_false(argc == 2,"exactly one input argument required"); timer_start(); //-------------------------------------------------------------------// // counters int i, n; // file paths char *input_file_path, *geometry_file_path, *case_file_path, *data_file_path, *data_numbered_file_path, *display_file_path, *display_numbered_file_path; exit_if_false(geometry_file_path = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating geometry file path"); exit_if_false(case_file_path = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating case file path"); exit_if_false(data_file_path = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating data file path"); exit_if_false(data_numbered_file_path = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating data numbered file path"); exit_if_false(display_file_path = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating display file path"); exit_if_false(display_numbered_file_path = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating display numbered file path"); // print string char *print; exit_if_false(print = (char *)malloc(MAX_STRING_LENGTH * sizeof(char)),"allocating the print string"); // mesh structures int n_nodes, n_faces, n_elements, n_boundaries_old = 0, n_boundaries, n_terms; struct NODE *node; struct FACE *face; struct ELEMENT *element; struct BOUNDARY *boundary_old = NULL, *boundary; struct TERM *term; EXPRESSION *initial = NULL; // solution vectors int n_u_old = 0, n_u; double *u_old = NULL, *u; // files FILE *input_file, *case_file, *data_file, *geometry_file, *display_file; //-------------------------------------------------------------------// // opening the input file print_info("opening the input file %s",argv[1]); input_file_path = argv[1]; input_file = fopen(input_file_path,"r"); exit_if_false(input_file != NULL,"opening %s",input_file_path); // reading the case file path print_info("reading the case file path"); exit_if_false(fetch_value(input_file,"case_file_path",'s',case_file_path) == FETCH_SUCCESS,"reading case_file_path from %s",input_file_path); print_continue(case_file_path); // reading the number of variables, variable names and orders print_info("reading the variables"); int n_variables_old = 0, n_variables; exit_if_false(fetch_value(input_file,"number_of_variables",'i',&n_variables) == FETCH_SUCCESS,"reading number_of_variables from %s",input_file_path); int *variable_order_old = NULL, *variable_order = (int *)malloc(n_variables * sizeof(int)); exit_if_false(variable_order != NULL,"allocating orders"); exit_if_false(fetch_vector(input_file, "variable_order", 'i', n_variables, variable_order) == FETCH_SUCCESS,"reading variable_order from %s",input_file_path); char **variable_name = allocate_character_matrix(NULL,n_variables,MAX_STRING_LENGTH); exit_if_false(variable_name != NULL,"allocating variable names"); warn_if_false(fetch_vector(input_file,"variable_name",'s',n_variables,variable_name) == FETCH_SUCCESS,"reading variable_name from %s",input_file_path); for(i = 0; i < n_variables; i ++) print_continue("%s order %i",variable_name[i],variable_order[i]); // reading the number of inner and outer iterations to perform print_info("reading the numbers of iterations"); int outer_iteration = 0, inner_iteration; int n_outer_iterations, n_inner_iterations, data_n_outer_iterations, display_n_outer_iterations; exit_if_false(fetch_value(input_file,"number_of_inner_iterations",'i',&n_inner_iterations) == FETCH_SUCCESS,"reading number_of_inner_iterations from %s",input_file_path); exit_if_false(fetch_value(input_file,"number_of_outer_iterations",'i',&n_outer_iterations) == FETCH_SUCCESS,"reading number_of_outer_iterations from %s",input_file_path); print_continue("%i outer of %i inner iterations to be done",n_outer_iterations,n_inner_iterations); // read existing case and data case_file = fopen(case_file_path,"r"); if(case_file != NULL) { print_info("reading existing case file %s",case_file_path); read_case(case_file, &n_variables_old, &variable_order_old, &n_nodes, &node, &n_faces, &face, &n_elements, &element, &n_boundaries_old, &boundary_old); fclose(case_file); n = 0; for(i = 0; i < n_variables; i ++) n += n_elements*ORDER_TO_N_BASIS(variable_order[i]); if(fetch_value(input_file,"initial_data_file_path",'s',data_file_path) == FETCH_SUCCESS) { print_info("reading existing data file %s",data_file_path); exit_if_false(data_file = fopen(data_file_path,"r"),"opening %s",data_file_path); read_data(data_file, &n_u_old, &u_old, &outer_iteration); fclose(data_file); exit_if_false(n_u_old == n,"case and initial data does not match"); } } // construct new case else { print_info("reading the geometry file path"); exit_if_false(fetch_value(input_file,"geometry_file_path",'s',geometry_file_path) == FETCH_SUCCESS,"reading geometry_file_path from %s",input_file_path); print_continue(geometry_file_path); print_info("reading the geometry file %s",geometry_file_path); exit_if_false(geometry_file = fopen(geometry_file_path,"r"),"opening %s",geometry_file_path); read_geometry(geometry_file, &n_nodes, &node, &n_faces, &face, &n_elements, &element); fclose(geometry_file); print_continue("%i nodes, %i faces and %i elements",n_nodes,n_faces,n_elements); print_info("generating additional connectivity and geometry"); process_geometry(n_nodes, node, n_faces, face, n_elements, element); } // read the data file path and output frequency print_info("reading the data file path and output frequency"); exit_if_false(fetch_value(input_file,"data_file_path",'s',data_file_path) == FETCH_SUCCESS,"reading data_file_path from %s",input_file_path); if(fetch_value(input_file,"data_number_of_outer_iterations",'i',&data_n_outer_iterations) != FETCH_SUCCESS) data_n_outer_iterations = n_outer_iterations + outer_iteration; print_continue("data to be written to %s every %i outer iterations",data_file_path,data_n_outer_iterations); // read boundaries print_info("reading boundaries"); boundaries_input(input_file, n_faces, face, &n_boundaries, &boundary); print_continue("%i boundaries",n_boundaries); // read terms print_info("reading PDE terms"); terms_input(input_file, &n_terms, &term); print_continue("%i terms",n_terms); // update unknown indices and values print_info("updating the numbering of the degrees of freedom"); update_element_unknowns(n_variables_old, n_variables, variable_order_old, variable_order, n_elements, element, n_u_old, &n_u, u_old, &u); print_continue("%i degrees of freedom",n_u); // update face boundaries print_info("updating the face boundary associations"); update_face_boundaries(n_variables, n_faces, face, n_boundaries, boundary); // update integration print_info("updating integration"); i = update_face_integration(n_variables_old, n_variables, variable_order_old, variable_order, n_faces, face); if(i) print_continue("updated %i face quadratures",i); i = update_element_integration(n_variables_old, n_variables, variable_order_old, variable_order, n_elements, element); if(i) print_continue("updated %i element quadratures",i); // update numerics print_info("updating numerics"); i = update_face_numerics(n_variables_old, n_variables, variable_order_old, variable_order, n_faces, face, n_boundaries_old, boundary_old); if(i) print_continue("updated %i face interpolations",i); i = update_element_numerics(n_variables_old, n_variables, variable_order_old, variable_order, n_elements, element); if(i) print_continue("updated %i element interpolations",i); // write case file print_info("writing case file %s",case_file_path); exit_if_false(case_file = fopen(case_file_path,"w"),"opening %s",case_file_path); write_case(case_file, n_variables, variable_order, n_nodes, node, n_faces, face, n_elements, element, n_boundaries, boundary); fclose(case_file); // read the display file path and output frequency print_info("reading the display file path and output frequency"); if( fetch_value(input_file,"display_file_path",'s',display_file_path) == FETCH_SUCCESS && fetch_value(input_file,"display_number_of_outer_iterations",'i',&display_n_outer_iterations) == FETCH_SUCCESS ) print_continue("display to be written to %s every %i outer iterations",display_file_path,display_n_outer_iterations); else { display_n_outer_iterations = 0; warn_if_false(0,"display files will not be written"); } // initialise if(initial_input(input_file, n_variables, &initial)) { print_info("initialising the degrees of freedom"); initialise_values(n_variables, variable_order, n_elements, element, initial, u); } //-------------------------------------------------------------------// // allocate and initialise the system print_info("allocating and initialising the system"); SPARSE system = NULL; initialise_system(n_variables, variable_order, n_elements, element, n_u, &system); double *residual, *max_residual, *du, *max_du; exit_if_false(residual = (double *)malloc(n_u * sizeof(double)),"allocating the residuals"); exit_if_false(max_residual = (double *)malloc(n_variables * sizeof(double)),"allocating the maximum residuals"); exit_if_false(du = (double *)malloc(n_u * sizeof(double)),"allocating du"); exit_if_false(max_du = (double *)malloc(n_variables * sizeof(double)),"allocating the maximum changes"); exit_if_false(u_old = (double *)realloc(u_old, n_u * sizeof(double)),"re-allocating u_old"); timer_reset(); // iterate print_info("iterating"); n_outer_iterations += outer_iteration; for(; outer_iteration < n_outer_iterations; outer_iteration ++) { print_output("iteration %i", outer_iteration); for(i = 0; i < n_u; i ++) u_old[i] = u[i]; for(inner_iteration = 0; inner_iteration < n_inner_iterations; inner_iteration ++) { calculate_system(n_variables, variable_order, n_faces, face, n_elements, element, n_terms, term, n_u, u_old, u, system, residual); exit_if_false(sparse_solve(system, du, residual) == SPARSE_SUCCESS,"solving system"); for(i = 0; i < n_u; i ++) u[i] -= du[i]; calculate_maximum_changes_and_residuals(n_variables, variable_order, n_elements, element, du, max_du, residual, max_residual); for(i = 0; i < n_variables; i ++) sprintf(&print[26*i],"%.6e|%.6e ",max_du[i],max_residual[i]); print_continue("%s",print); } slope_limit(n_variables, variable_order, n_nodes, node, n_elements, element, n_boundaries, boundary, u); if(data_n_outer_iterations && outer_iteration % data_n_outer_iterations == 0) { generate_numbered_file_path(data_numbered_file_path, data_file_path, outer_iteration); print_info("writing data to %s",data_numbered_file_path); exit_if_false(data_file = fopen(data_numbered_file_path,"w"),"opening %s",data_numbered_file_path); write_data(data_file, n_u, u, outer_iteration); fclose(data_file); } if(display_n_outer_iterations && outer_iteration % display_n_outer_iterations == 0) { generate_numbered_file_path(display_numbered_file_path, display_file_path, outer_iteration); print_info("writing display to %s",data_numbered_file_path); exit_if_false(display_file = fopen(display_numbered_file_path,"w"),"opening %s",display_numbered_file_path); write_display(display_file, n_variables, variable_name, variable_order, n_elements, element, n_u, u); fclose(display_file); } timer_print(); } //-------------------------------------------------------------------// print_info("freeing all memory"); fclose(input_file); free(geometry_file_path); free(case_file_path); free(data_file_path); free(data_numbered_file_path); free(display_file_path); free(display_numbered_file_path); free(print); destroy_nodes(n_nodes,node); destroy_faces(n_faces,face,n_variables); destroy_elements(n_elements,element,n_variables); destroy_boundaries(n_boundaries_old,boundary_old); destroy_boundaries(n_boundaries,boundary); destroy_terms(n_terms,term); destroy_initial(n_variables,initial); free(variable_order_old); free(variable_order); destroy_matrix((void *)variable_name); free(u_old); free(u); sparse_destroy(system); free(residual); free(max_residual); free(du); free(max_du); return 0; }
int main(int argc, char* argv[]) { bool hermite; int n1, n2, npml, pad1, pad2, ns, nw, iw; float d1, d2, **v, ds, os, ow, dw; double omega; sf_complex ***f; sf_file in, out, source; int uts, mts; char *order; sf_init(argc, argv); in = sf_input("in"); out = sf_output("out"); if (!sf_getint("uts",&uts)) uts=0; //#ifdef _OPENMP // mts = omp_get_max_threads(); //#else mts = 1; //#endif uts = (uts < 1)? mts: uts; sf_warning("Using %d out of %d threads!", uts, mts); if (!sf_getbool("hermite",&hermite)) hermite=false; /* Hermite operator */ if (!sf_getint("npml",&npml)) npml=20; /* PML width */ if (NULL == (order = sf_getstring("order"))) order="j"; /* discretization scheme (default optimal 9-point) */ fdprep_order(order); /* read input dimension */ if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input."); if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input."); if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input."); if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input."); v = sf_floatalloc2(n1,n2); sf_floatread(v[0],n1*n2,in); /* PML padding */ pad1 = n1+2*npml; pad2 = n2+2*npml; /* read source */ if (NULL == sf_getstring("source")) sf_error("Need source="); source = sf_input("source"); if (!sf_histint(source,"n3",&ns)) sf_error("No ns=."); if (!sf_histfloat(source,"d3",&ds)) ds=d2; if (!sf_histfloat(source,"o3",&os)) os=0.; if (!sf_histint(source,"n4",&nw)) sf_error("No nw=."); if (!sf_histfloat(source,"d4",&dw)) sf_error("No dw=."); if (!sf_histfloat(source,"o4",&ow)) sf_error("No ow=."); f = sf_complexalloc3(n1,n2,ns); /* write out forward simulation */ sf_settype(out,SF_COMPLEX); sf_putint(out,"n3",ns); sf_putfloat(out,"d3",ds); sf_putfloat(out,"o3",os); sf_putstring(out,"label3","Shot"); sf_putstring(out,"unit3",""); sf_putint(out,"n4",nw); sf_putfloat(out,"d4",dw); sf_putfloat(out,"o4",ow); sf_putstring(out,"label4","Frequency"); sf_putstring(out,"unit4","Hz"); /* Loop over frequency */ for (iw=0; iw<nw; iw++ ) { omega=(double) 2.*SF_PI*(ow+iw*dw); sf_warning("Calculating frequency %d out of %d for %f HZ.",iw+1,nw,ow+iw*dw); /* read in source */ sf_complexread(f[0][0],n1*n2*ns,source); /* initialize sparse solver */ sparse_init(uts, pad1, pad2); /* factorize matrix, change according to different frequencies and models */ sparse_factor(omega, n1, n2, d1, d2, v, npml, pad1, pad2); /* sparse solver */ sparse_solve(npml, pad1, pad2, f, hermite, ns, uts); /* write out wavefield */ sf_complexwrite(f[0][0],n1*n2*ns,out); sparse_free(uts); } exit(0); }