int run_simulation(struct simulation *sim) { struct device cell; log_clear(sim); printf_log(sim,_("Run_simulation\n")); device_init(&cell); cell.onlypos=FALSE; dump_init(sim,&cell); set_dump_status(sim,dump_stop_plot, FALSE); set_dump_status(sim,dump_print_text, TRUE); char temp[1000]; cell.kl_in_newton=FALSE; //if (strcmp(outputpath,"")!=0) strcpy(get_output_path(sim),outputpath); //if (strcmp(inputpath,"")!=0) strcpy(get_input_path(sim),inputpath); dump_load_config(sim,&cell); int i; int z; int x; int y; join_path(2,temp,get_output_path(sim),"error.dat"); remove(temp); join_path(2,temp,get_output_path(sim),"equilibrium"); remove_dir(sim,temp); join_path(2,temp,get_output_path(sim),"snapshots"); remove_dir(sim,temp); join_path(2,temp,get_output_path(sim),"light_dump"); remove_dir(sim,temp); join_path(2,temp,get_output_path(sim),"dynamic"); remove_dir(sim,temp); join_path(2,temp,get_output_path(sim),"frequency"); remove_dir(sim,temp); load_config(sim,&cell); if (strcmp(sim->force_sim_mode,"")!=0) { strcpy(cell.simmode,sim->force_sim_mode); } if (strcmp(cell.simmode,"opticalmodel@optics")!=0) { solver_init(sim,cell.solver_name); newton_init(sim,cell.newton_name); printf_log(sim,_("Loading DoS for %d layers\n"),cell.my_epitaxy.electrical_layers); char tempn[100]; char tempp[100]; i=0; for (i=0;i<cell.my_epitaxy.electrical_layers;i++) { dos_init(&cell,i); printf_log(sim,"Load DoS %d/%d\n",i,cell.my_epitaxy.electrical_layers); sprintf(tempn,"%s_dosn.dat",cell.my_epitaxy.dos_file[i]); sprintf(tempp,"%s_dosp.dat",cell.my_epitaxy.dos_file[i]); load_dos(sim,&cell,tempn,tempp,i); } device_alloc_traps(&cell); if (get_dump_status(sim,dump_write_converge)==TRUE) { sim->converge = fopena(get_output_path(sim),"converge.dat","w"); fclose(sim->converge); sim->tconverge=fopena(get_output_path(sim),"tconverge.dat","w"); fclose(sim->tconverge); } mesh_cal_layer_widths(&cell); long double depth=0.0; long double percent=0.0; long double value=0.0; for (z=0;z<cell.zmeshpoints;z++) { for (x=0;x<cell.xmeshpoints;x++) { for (y=0;y<cell.ymeshpoints;y++) { depth=cell.ymesh[y]-cell.layer_start[cell.imat[z][x][y]]; percent=depth/cell.layer_width[cell.imat[z][x][y]]; cell.Nad[z][x][y]=get_dos_doping_start(&cell,cell.imat[z][x][y])+(get_dos_doping_stop(&cell,cell.imat[z][x][y])-get_dos_doping_start(&cell,cell.imat[z][x][y]))*percent; } } } init_mat_arrays(&cell); for (z=0;z<cell.zmeshpoints;z++) { for (x=0;x<cell.xmeshpoints;x++) { for (y=0;y<cell.ymeshpoints;y++) { cell.phi[z][x][y]=0.0; cell.R[z][x][y]=0.0; cell.n[z][x][y]=0.0; } } } contacts_load(sim,&cell); cell.C=cell.xlen*cell.zlen*epsilon0*cell.epsilonr[0][0][0]/(cell.ylen+cell.other_layers); if (get_dump_status(sim,dump_print_text)==TRUE) printf_log(sim,"C=%Le\n",cell.C); cell.A=cell.xlen*cell.zlen; cell.Vol=cell.xlen*cell.zlen*cell.ylen; ///////////////////////light model char old_model[100]; gdouble old_Psun=0.0; old_Psun=light_get_sun(&cell.mylight); light_init(&cell.mylight); light_set_dx(&cell.mylight,cell.ymesh[1]-cell.ymesh[0]); light_load_config(sim,&cell.mylight); if (cell.led_on==TRUE) { strcpy(old_model,cell.mylight.mode); strcpy(cell.mylight.mode,"ray"); } light_load_dlls(sim,&cell.mylight); light_setup_ray(sim,&cell,&cell.mylight); if (cell.led_on==TRUE) { cell.mylight.force_update=TRUE; light_set_sun(&(cell.mylight),1.0); light_set_sun_delta_at_wavelength(&(cell.mylight),cell.led_wavelength); light_solve_all(sim,&(cell.mylight)); cell.mylight.force_update=FALSE; strcpy(cell.mylight.mode,old_model); light_set_sun(&(cell.mylight),old_Psun); light_free_dlls(sim,&cell.mylight); light_load_dlls(sim,&cell.mylight); } /////////////////////// //update_arrays(&cell); contact_set_all_voltages(sim,&cell,0.0); get_initial(sim,&cell); remesh_shrink(&cell); if (cell.math_enable_pos_solver==TRUE) { for (z=0;z<cell.zmeshpoints;z++) { for (x=0;x<cell.xmeshpoints;x++) { solve_pos(sim,&cell,z,x); } } } time_init(sim,&cell); cell.N=0; cell.M=0; solver_realloc(sim,&cell); plot_open(sim); cell.go_time=FALSE; plot_now(sim,"plot"); //set_solver_dump_every_matrix(1); find_n0(sim,&cell); //set_solver_dump_every_matrix(0); draw_gaus(&cell); if (cell.onlypos==TRUE) { join_path(2,temp,get_output_path(sim),"equilibrium"); dump_1d_slice(sim,&cell,temp); device_free(sim,&cell); device_free_traps(&cell); mesh_free(sim,&cell); return 0; } } //Load the dll if (is_domain(cell.simmode)!=0) { char gussed_full_mode[200]; if (guess_whole_sim_name(sim,gussed_full_mode,get_input_path(sim),cell.simmode)==0) { printf_log(sim,"I guess we are using running %s\n",gussed_full_mode); strcpy(cell.simmode,gussed_full_mode); }else { ewe(sim,"I could not guess which simulation to run from the mode %s\n",cell.simmode); } } run_electrical_dll(sim,&cell,strextract_domain(cell.simmode)); if (strcmp(cell.simmode,"opticalmodel@optics")!=0) { device_free(sim,&cell); device_free_traps(&cell); mesh_free(sim,&cell); plot_close(sim); for (i=0;i<cell.my_epitaxy.electrical_layers;i++) { dos_free(&cell,i); } solver_free_memory(sim,&cell); newton_interface_free(sim); light_free(sim,&cell.mylight); } return cell.odes; }
void dump_write_to_disk(struct simulation *sim,struct device* in) { char temp[200]; char postfix[100]; char snapshots_dir[PATH_MAX]; char out_dir[PATH_MAX]; char slice_info_file[PATH_MAX]; char snapshot_dir[PATH_MAX]; char sim_name[PATH_MAX]; strextract_name(sim_name,in->simmode); sprintf(snapshot_dir,"snapshots"); int dumped=FALSE; FILE* out; struct stat st = {0}; sprintf(postfix,"%d",dump_number); if ((get_dump_status(sim,dump_pl)==TRUE)||(get_dump_status(sim,dump_energy_slice_switch)==TRUE)||(get_dump_status(sim,dump_1d_slices)==TRUE)||(get_dump_status(sim,dump_optical_probe_spectrum)==TRUE)) { join_path(2,snapshots_dir,get_output_path(sim),snapshot_dir); if (stat(snapshots_dir, &st) == -1) { mkdir(snapshots_dir, 0700); } join_path(2,temp,snapshots_dir,"snapshots.inp"); out=fopen(temp,"w"); fprintf(out,"#end"); fclose(out); join_path(2,out_dir,snapshots_dir,postfix); if (stat(out_dir, &st) == -1) { mkdir(out_dir, 0700); } join_path(2,slice_info_file,out_dir,"snapshot_info.dat"); out=fopen(slice_info_file,"w"); if (out!=NULL) { fprintf(out,"#dump_voltage\n"); fprintf(out,"%Lf\n",get_equiv_V(sim,in)); fprintf(out,"#dump_time\n"); fprintf(out,"%Lf\n",in->time); fprintf(out,"#ver\n"); fprintf(out,"1.0\n"); fprintf(out,"#end\n"); fclose(out); }else { ewe(sim,"Can't write to file %s\n",slice_info_file); } } if (get_dump_status(sim,dump_optical_probe_spectrum)==TRUE) { dump_probe_spectrum(sim,in,out_dir,dump_number); dumped=TRUE; } if (get_dump_status(sim,dump_1d_slices)==TRUE) { dump_1d_slice(sim,in,out_dir); dump_device_map(out_dir,in); dumped=TRUE; } if (get_dump_status(sim,dump_energy_slice_switch)==TRUE) { dump_energy_slice(out_dir,in); dumped=TRUE; } if (get_dump_status(sim,dump_pl)==TRUE) { exp_cal_emission(sim,dump_number,in); dumped=TRUE; } if (dumped==TRUE) { dump_number++; } }
void exp_cal_emission(struct simulation *sim,int number,struct device *in) { double Re_h=0.0; double Re_e=0.0; double Rh_e=0.0; double Rh_h=0.0; double dEe_e=0.0; double dEe_h=0.0; double dEh_e=0.0; double dEh_h=0.0; char name[100]; char out_dir[400]; int x; int y; int z; int band; struct buffer buf; char temp[200]; int mat=0; double pl_fe_fh=0.0; double pl_fe_te=0.0; double pl_te_fh=0.0; double pl_th_fe=0.0; double pl_ft_th=0.0; int pl_enabled=0; char snapshot_dir[200]; char sim_name[200]; double Vexternal=get_equiv_V(sim,in); //char zip_file_name[400]; buffer_init(&buf); //sprintf(zip_file_name,"%s/snapshots.zip",get_output_path(sim)); //buffer_zip_set_name(&buf,zip_file_name); struct istruct fe_to_fh; struct istruct fe_to_te; struct istruct te_to_fh; struct istruct fh_to_th; struct istruct th_to_fe; double max_Eg=0.0; for (z=0;z<in->zmeshpoints;z++) { for (x=0;x<in->xmeshpoints;x++) { for (y=0;y<in->ymeshpoints;y++) { if (in->Eg[z][x][y]>max_Eg) { max_Eg=in->Eg[z][x][y]; } } } } //inter_init_mesh(&photons,40,0.0,2.254); inter_init(&fe_to_fh); inter_init(&fe_to_te); inter_init(&te_to_fh); inter_init(&fh_to_th); inter_init(&th_to_fe); //double Re_e=0.0; int pl_data_added=FALSE; for (z=0;z<in->zmeshpoints;z++) { for (x=0;x<in->xmeshpoints;x++) { for (y=0;y<in->ymeshpoints;y++) { mat=in->imat[z][x][y]; pl_fe_fh=get_pl_fe_fh(in,mat); pl_fe_te=get_pl_fe_te(in,mat); pl_te_fh=get_pl_te_fh(in,mat); pl_th_fe=get_pl_th_fe(in,mat); pl_ft_th=get_pl_ft_th(in,mat); pl_enabled=get_pl_enabled(in,mat); if (pl_enabled==TRUE) { pl_data_added=TRUE; inter_append(&fe_to_fh,in->Eg[z][x][y],in->Rfree[z][x][y]*pl_fe_fh); for (band=0;band<in->srh_bands;band++) { //electrons dEe_e= -dos_get_band_energy_n(in,band,mat); Re_e=(in->nt_r1[z][x][y][band]-in->nt_r2[z][x][y][band])*pl_fe_te; //electron capture - electron emission for an electron trap inter_append(&fe_to_te,dEe_e,Re_e); dEe_h=get_dos_Eg(in,mat)-dEe_e; Re_h=(in->nt_r3[z][x][y][band]-in->nt_r4[z][x][y][band])*pl_te_fh; //hole capture-hole emission for an electron trap inter_append(&te_to_fh,dEe_h,Re_h); //holes dEh_e=get_dos_Eg(in,mat)-dEh_h; Rh_e=(in->pt_r3[z][x][y][band]-in->pt_r4[z][x][y][band])*pl_th_fe; //electron capture - electron emission for a hole trap inter_append(&th_to_fe,dEh_e,Rh_e); dEh_h= -dos_get_band_energy_p(in,band,mat); Rh_h=(in->pt_r1[z][x][y][band]-in->pt_r2[z][x][y][band])*pl_ft_th; //hole capture - hole emission for a hole trap inter_append(&fh_to_th,dEh_h,Rh_h); } } } } } inter_mul(&fe_to_fh,in->ylen/((double)in->ymeshpoints)); inter_mul(&fe_to_te,in->ylen/((double)in->ymeshpoints)); inter_mul(&te_to_fh,in->ylen/((double)in->ymeshpoints)); inter_mul(&th_to_fe,in->ylen/((double)in->ymeshpoints)); inter_mul(&fh_to_th,in->ylen/((double)in->ymeshpoints)); sprintf(temp,"%d",number); strextract_name(sim_name,in->simmode); sprintf(snapshot_dir,"snapshots"); join_path(3,out_dir,get_output_path(sim),snapshot_dir,temp); //inter_dump(&fe_to_fh); //inter_sort(&fe_to_fh); if (pl_data_added==TRUE) { inter_sort(&fe_to_te); inter_sort(&te_to_fh); inter_sort(&th_to_fe); inter_sort(&fh_to_th); inter_join_bins(&fe_to_fh,0.01); inter_join_bins(&fe_to_te,0.01); inter_join_bins(&te_to_fh,0.01); inter_join_bins(&th_to_fe,0.01); inter_join_bins(&fh_to_th,0.01); light_energy=0.0; light_energy+=calculate_photon_energy(&fe_to_fh)*in->area; light_energy+=calculate_photon_energy(&fe_to_te)*in->area; light_energy+=calculate_photon_energy(&te_to_fh)*in->area; light_energy+=calculate_photon_energy(&th_to_fe)*in->area; light_energy+=calculate_photon_energy(&fh_to_th)*in->area; buffer_malloc(&buf); sprintf(name,"%s","fe_to_fh.dat"); buf.y_mul=1.0; buf.x_mul=1e9; strcpy(buf.title,"PL Spectra Free electron to free hole"); strcpy(buf.type,"xy"); strcpy(buf.x_label,"Energy"); strcpy(buf.y_label,"Intensity"); strcpy(buf.x_units,"eV"); strcpy(buf.y_units,"m^{-3}s^{-1}"); buf.logscale_x=0; buf.logscale_y=0; buf.time=in->time; buf.Vexternal=Vexternal; buffer_add_info(&buf); buffer_add_xy_data(&buf,fe_to_fh.x, fe_to_fh.data, fe_to_fh.len); buffer_dump_path(out_dir,name,&buf); buffer_free(&buf); buffer_malloc(&buf); sprintf(name,"%s","te_to_fh.dat"); buf.y_mul=1.0; buf.x_mul=1e9; strcpy(buf.title,"PL Spectra Free hole to trapped electron"); strcpy(buf.type,"xy"); strcpy(buf.x_label,"Energy"); strcpy(buf.y_label,"Intensity"); strcpy(buf.x_units,"eV"); strcpy(buf.y_units,"m^{-3}s^{-1}"); buf.logscale_x=0; buf.logscale_y=0; buf.time=in->time; buf.Vexternal=Vexternal; buffer_add_info(&buf); buffer_add_xy_data(&buf,te_to_fh.x, te_to_fh.data, te_to_fh.len); buffer_dump_path(out_dir,name,&buf); buffer_free(&buf); buffer_malloc(&buf); sprintf(name,"%s","fe_to_te.dat"); buf.y_mul=1.0; buf.x_mul=1e9; strcpy(buf.title,"PL Spectra free electron to trapped electron"); strcpy(buf.type,"xy"); strcpy(buf.x_label,"Energy"); strcpy(buf.y_label,"Intensity"); strcpy(buf.x_units,"eV"); strcpy(buf.y_units,"m^{-3}s^{-1}"); buf.logscale_x=0; buf.logscale_y=0; buf.time=in->time; buf.Vexternal=Vexternal; buffer_add_info(&buf); buffer_add_xy_data(&buf,fe_to_te.x, fe_to_te.data, fe_to_te.len); buffer_dump_path(out_dir,name,&buf); buffer_free(&buf); buffer_malloc(&buf); sprintf(name,"%s","th_to_fe.dat"); buf.y_mul=1.0; buf.x_mul=1e9; strcpy(buf.title,"PL Spectra Free electron to trapped hole"); strcpy(buf.type,"xy"); strcpy(buf.x_label,"Energy"); strcpy(buf.y_label,"Intensity"); strcpy(buf.x_units,"eV"); strcpy(buf.y_units,"m^{-3}s^{-1}"); buf.logscale_x=0; buf.logscale_y=0; buf.time=in->time; buf.Vexternal=Vexternal; buffer_add_info(&buf); buffer_add_xy_data(&buf,th_to_fe.x, th_to_fe.data, th_to_fe.len); buffer_dump_path(out_dir,name,&buf); buffer_free(&buf); buffer_malloc(&buf); sprintf(name,"%s","fh_to_th.dat"); buf.y_mul=1.0; buf.x_mul=1e9; strcpy(buf.title,"PL Spectra free hole to trapped hole"); strcpy(buf.type,"xy"); strcpy(buf.x_label,"Energy"); strcpy(buf.y_label,"Intensity"); strcpy(buf.x_units,"eV"); strcpy(buf.y_units,"m^{-3}s^{-1}"); buf.logscale_x=0; buf.logscale_y=0; buf.time=in->time; buf.Vexternal=Vexternal; buffer_add_info(&buf); buffer_add_xy_data(&buf,fh_to_th.x, fh_to_th.data, fh_to_th.len); buffer_dump_path(out_dir,name,&buf); buffer_free(&buf); } inter_free(&fe_to_fh); inter_free(&fe_to_te); inter_free(&te_to_fh); inter_free(&th_to_fe); inter_free(&fh_to_th); return; }
void get_initial(struct simulation *sim,struct device *in) { int i; int z; int x; int y; gdouble Ef=0.0; gdouble phi_ramp=0.0; gdouble Eg=0.0; gdouble Xi=0.0; gdouble charge_left=0.0; gdouble charge_right=0.0; gdouble top_l=0.0; gdouble top_r=0.0; Ef=0.0; phi_ramp=0.0; Eg=in->Eg[0][0][0]; Xi=in->Xi[0][0][0]; charge_left=in->lcharge; charge_right=in->rcharge; top_l=0.0; top_r=0.0; if (in->interfaceleft==TRUE) { top_l=in->phibleft-Eg; }else { if (in->lr_pcontact==LEFT) { top_l=get_top_from_p(in,charge_left,in->Te[0][0][0],in->imat[0][0][0]); }else { top_l= -(in->Eg[0][0][0]+get_top_from_n(in,charge_left,in->Te[0][0][0],in->imat[0][0][0])); } } if (in->interfaceright==TRUE) { top_r= -in->phibright; }else { if (in->lr_pcontact==LEFT) { top_r=get_top_from_n(in,charge_right,in->Te[0][0][in->ymeshpoints-1],in->imat[0][0][in->ymeshpoints-1]); }else { top_r= -(Eg+get_top_from_p(in,charge_right,in->Te[0][0][in->ymeshpoints-1],in->imat[0][0][in->ymeshpoints-1])); } } if (get_dump_status(sim,dump_info_text)==TRUE) { printf_log(sim,"check1= %Le %Le\n",get_p_den(in,top_l,in->Te[0][0][0],in->imat[0][0][0]),charge_left); printf_log(sim,"check2= %Le %Le\n",get_n_den(in,top_r,in->Te[0][0][in->ymeshpoints-1],in->imat[0][0][in->ymeshpoints-1]),charge_right); } gdouble delta_phi=top_l+top_r+in->Eg[0][0][0]+in->Xi[0][0][0]-in->Xi[0][0][in->ymeshpoints-1]; gdouble test_l= -in->Xi[0][0][0]+top_r; gdouble test_r= -in->Xi[0][0][0]-in->Eg[0][0][0]-top_l; in->vbi=delta_phi; if (get_dump_status(sim,dump_print_text)==TRUE) { printf_log(sim,"delta=%Le\n",delta_phi); printf_log(sim,">>>>top_l= %Le\n",top_l+Eg); printf_log(sim,">>>>top_r= %Le\n",-top_r); printf_log(sim,"left= %Le right = %Le %Le %Le\n",test_l,test_r,test_r-test_l,delta_phi); printf_log(sim,"%Le %Le %Le %Le %Le\n",top_l,top_r,Eg,delta_phi,in->phi[0][0][0]); } Ef= -(top_l+Xi+Eg); gdouble Lp=get_p_den(in,(-in->Xi[0][0][0]-in->phi[0][0][0]-Eg)-Ef,in->Th[0][0][0],in->imat[0][0][0]); gdouble Ln=get_n_den(in,Ef-(-in->Xi[0][0][0]-in->phi[0][0][0]),in->Te[0][0][0],in->imat[0][0][0]); gdouble Rp=get_p_den(in,(-in->Xi[0][0][in->ymeshpoints-1]-delta_phi-Eg)-Ef,in->Th[0][0][in->ymeshpoints-1],in->imat[0][0][in->ymeshpoints-1]); gdouble Rn=get_n_den(in,Ef-(-in->Xi[0][0][in->ymeshpoints-1]-delta_phi),in->Te[0][0][in->ymeshpoints-1],in->imat[0][0][in->ymeshpoints-1]); in->l_electrons=Ln; in->l_holes=Lp; in->r_electrons=Rn; in->r_holes=Rp; if (get_dump_status(sim,dump_built_in_voltage)==TRUE) { printf_log(sim,"Ef=%Le\n",Ef); printf_log(sim,"Holes on left contact = %Le\n", Lp); printf_log(sim,"Electrons on left contact = %Le\n", Ln); printf_log(sim,"Holes on right contact = %Le\n", Rp); printf_log(sim,"Electrons on right contact = %Le\n", Rn); FILE *contacts=fopena(get_output_path(sim),"initial.dat","w"); fprintf (contacts,"#left_holes\n"); fprintf (contacts,"%Le\n", Lp); fprintf (contacts,"#left_electrons\n"); fprintf (contacts,"%Le\n", Ln); fprintf (contacts,"#right_holes\n"); fprintf (contacts,"%Le\n", Rp); fprintf (contacts,"#right_electrons\n"); fprintf (contacts,"%Le\n", Rn); fprintf (contacts,"#Vbi\n"); fprintf (contacts,"%Le\n", in->vbi); fprintf (contacts,"#end\n"); fclose(contacts); } int band; for (z=0;z<in->zmeshpoints;z++) { for (x=0;x<in->xmeshpoints;x++) { for (y=0;y<in->ymeshpoints;y++) { phi_ramp=delta_phi*(in->ymesh[y]/in->ymesh[in->ymeshpoints-1]); in->Fi[z][x][y]=Ef; in->Fn[z][x][y]=Ef; in->Fp[z][x][y]=Ef; in->phi[z][x][y]=phi_ramp; in->x[z][x][y]=in->phi[z][x][y]+in->Fn[z][x][y]; in->xp[z][x][y]= -(in->phi[z][x][y]+in->Fp[z][x][y]); in->Ec[z][x][y]= -in->phi[z][x][y]-in->Xi[z][x][y]; if (in->Ec[z][x][y]<in->Fi[z][x][y]) { in->phi[z][x][y]= -(in->Fi[z][x][y]+in->Xi[z][x][y]); in->Ec[z][x][y]= -in->phi[z][x][y]-in->Xi[z][x][y]; } in->Ev[z][x][y]= -in->phi[z][x][y]-in->Xi[z][x][y]-in->Eg[z][x][y]; if (in->Ev[z][x][y]>in->Fi[z][x][y]) { in->phi[z][x][y]= -(in->Fi[z][x][y]+in->Xi[z][x][y]+in->Eg[z][x][y]); in->Ev[z][x][y]= -in->phi[z][x][y]-in->Xi[z][x][y]-in->Eg[z][x][y]; in->Ec[z][x][y]= -in->phi[z][x][y]-in->Xi[z][x][y]; } gdouble t=in->Fi[z][x][y]-in->Ec[z][x][y]; gdouble tp=in->Ev[z][x][y]-in->Fi[z][x][y]; in->n[z][x][y]=in->Nc[z][x][y]*exp(((t)*Q)/(kb*in->Te[z][x][y])); in->p[z][x][y]=in->Nv[z][x][y]*exp(((tp)*Q)/(kb*in->Th[z][x][y])); //printf("%Le %Le\n",t,tp); //getchar(); in->mun[z][x][y]=get_n_mu(in,in->imat[z][x][y]); in->mup[z][x][y]=get_p_mu(in,in->imat[z][x][y]); for (band=0;band<in->srh_bands;band++) { in->Fnt[z][x][y][band]= -in->phi[z][x][y]-in->Xi[z][x][y]+dos_srh_get_fermi_n(in,in->n[z][x][y], in->p[z][x][y],band,in->imat[z][x][y],in->Te[z][x][y]); in->Fpt[z][x][y][band]= -in->phi[z][x][y]-in->Xi[z][x][y]-in->Eg[z][x][y]-dos_srh_get_fermi_p(in,in->n[z][x][y], in->p[z][x][y],band,in->imat[z][x][y],in->Th[z][x][y]); in->xt[z][x][y][band]=in->phi[z][x][y]+in->Fnt[z][x][y][band]; in->nt[z][x][y][band]=get_n_pop_srh(sim,in,in->xt[z][x][y][band]+in->tt[z][x][y],in->Te[z][x][y],band,in->imat[z][x][y]); in->dnt[z][x][y][band]=get_dn_pop_srh(sim,in,in->xt[z][x][y][band]+in->tt[z][x][y],in->Te[z][x][y],band,in->imat[z][x][y]); in->xpt[z][x][y][band]= -(in->phi[z][x][y]+in->Fpt[z][x][y][band]); in->pt[z][x][y][band]=get_p_pop_srh(sim,in,in->xpt[z][x][y][band]-in->tpt[z][x][y],in->Th[z][x][y],band,in->imat[z][x][y]); in->dpt[z][x][y][band]=get_dp_pop_srh(sim,in,in->xpt[z][x][y][band]-in->tpt[z][x][y],in->Th[z][x][y],band,in->imat[z][x][y]); } } } } in->Vl=0.0; in->Vr=delta_phi; in->Vbi=delta_phi; init_dump(sim,in); //getchar(); if (in->stoppoint==1) exit(0); return; }
int convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int output_bps, int output_is_float, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort) { if (deadbeef->pl_get_item_duration (it) <= 0) { deadbeef->pl_lock (); const char *fname = deadbeef->pl_find_meta (it, ":URI"); fprintf (stderr, "converter: stream %s doesn't have finite length, skipped\n", fname); deadbeef->pl_unlock (); return -1; } char *path = outfolder[0] ? strdupa (outfolder) : strdupa (getenv("HOME")); if (!check_dir (path, 0755)) { fprintf (stderr, "converter: failed to create output folder: %s\n", outfolder); return -1; } int err = -1; FILE *enc_pipe = NULL; FILE *temp_file = NULL; DB_decoder_t *dec = NULL; DB_fileinfo_t *fileinfo = NULL; char out[PATH_MAX] = ""; // full path to output file char input_file_name[PATH_MAX] = ""; dec = (DB_decoder_t *)deadbeef->plug_get_for_id (deadbeef->pl_find_meta (it, ":DECODER")); if (dec) { fileinfo = dec->open (0); if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (it)) != 0) { deadbeef->pl_lock (); fprintf (stderr, "converter: failed to decode file %s\n", deadbeef->pl_find_meta (it, ":URI")); deadbeef->pl_unlock (); goto error; } if (fileinfo) { if (output_bps == -1) { output_bps = fileinfo->fmt.bps; output_is_float = fileinfo->fmt.is_float; } get_output_path (it, outfolder, outfile, encoder_preset, out, sizeof (out)); if (encoder_preset->method == DDB_ENCODER_METHOD_FILE) { const char *tmp = getenv ("TMPDIR"); if (!tmp) { tmp = "/tmp"; } snprintf (input_file_name, sizeof (input_file_name), "%s/ddbconvXXXXXX", tmp); mktemp (input_file_name); strcat (input_file_name, ".wav"); } else { strcpy (input_file_name, "-"); } char enc[2000]; memset (enc, 0, sizeof (enc)); // formatting: %o = outfile, %i = infile char *e = encoder_preset->encoder; char *o = enc; *o = 0; int len = sizeof (enc); while (e && *e) { if (len <= 0) { fprintf (stderr, "converter: failed to assemble encoder command line - buffer is not big enough, try to shorten your parameters. max allowed length is %u characters\n", (unsigned)sizeof (enc)); goto error; } if (e[0] == '%' && e[1]) { if (e[1] == 'o') { int l = snprintf (o, len, "\"%s\"", out); o += l; len -= l; } else if (e[1] == 'i') { int l = snprintf (o, len, "\"%s\"", input_file_name); o += l; len -= l; } else { strncpy (o, e, 2); o += 2; len -= 2; } e += 2; } else { *o++ = *e++; *o = 0; len--; } } fprintf (stderr, "converter: will encode using: %s\n", enc[0] ? enc : "internal RIFF WAVE writer"); if (!encoder_preset->encoder[0]) { // write to wave file temp_file = fopen (out, "w+b"); if (!temp_file) { fprintf (stderr, "converter: failed to open output wave file %s\n", out); goto error; } } else if (encoder_preset->method == DDB_ENCODER_METHOD_FILE) { temp_file = fopen (input_file_name, "w+b"); if (!temp_file) { fprintf (stderr, "converter: failed to open temp file %s\n", input_file_name); goto error; } } else { enc_pipe = popen (enc, "w"); if (!enc_pipe) { fprintf (stderr, "converter: failed to open encoder\n"); goto error; } } if (!temp_file) { temp_file = enc_pipe; } // write wave header char wavehdr_int[] = { 0x52, 0x49, 0x46, 0x46, 0x24, 0x70, 0x0d, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61 }; char wavehdr_float[] = { 0x52, 0x49, 0x46, 0x46, 0x2a, 0xdf, 0x02, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x28, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x02, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x16, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0xc5, 0x5b, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61 }; char *wavehdr = output_is_float ? wavehdr_float : wavehdr_int; int wavehdr_size = output_is_float ? sizeof (wavehdr_float) : sizeof (wavehdr_int); int header_written = 0; uint32_t outsize = 0; uint32_t outsr = fileinfo->fmt.samplerate; uint16_t outch = fileinfo->fmt.channels; int samplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8; int bs = 10250 * samplesize; char buffer[bs * 4]; int dspsize = bs / samplesize * sizeof (float) * fileinfo->fmt.channels; char dspbuffer[dspsize * 4]; int eof = 0; for (;;) { if (eof) { break; } if (abort && *abort) { break; } int sz = dec->read (fileinfo, buffer, bs); if (sz != bs) { eof = 1; } if (dsp_preset) { ddb_waveformat_t fmt; ddb_waveformat_t outfmt; memcpy (&fmt, &fileinfo->fmt, sizeof (fmt)); memcpy (&outfmt, &fileinfo->fmt, sizeof (fmt)); fmt.bps = 32; fmt.is_float = 1; deadbeef->pcm_convert (&fileinfo->fmt, buffer, &fmt, dspbuffer, sz); ddb_dsp_context_t *dsp = dsp_preset->chain; int frames = sz / samplesize; while (dsp) { frames = dsp->plugin->process (dsp, (float *)dspbuffer, frames, sizeof (dspbuffer) / (fmt.channels * 4), &fmt, NULL); dsp = dsp->next; } outsr = fmt.samplerate; outch = fmt.channels; outfmt.bps = output_bps; outfmt.is_float = output_is_float; outfmt.channels = outch; outfmt.samplerate = outsr; int n = deadbeef->pcm_convert (&fmt, dspbuffer, &outfmt, buffer, frames * sizeof (float) * fmt.channels); sz = n; } else if (fileinfo->fmt.bps != output_bps || fileinfo->fmt.is_float != output_is_float) { ddb_waveformat_t outfmt; memcpy (&outfmt, &fileinfo->fmt, sizeof (outfmt)); outfmt.bps = output_bps; outfmt.is_float = output_is_float; outfmt.channels = outch; outfmt.samplerate = outsr; int frames = sz / samplesize; int n = deadbeef->pcm_convert (&fileinfo->fmt, buffer, &outfmt, dspbuffer, frames * samplesize); memcpy (buffer, dspbuffer, n); sz = n; } outsize += sz; if (!header_written) { uint32_t size = (it->endsample-it->startsample) * outch * output_bps / 8; if (!size) { size = deadbeef->pl_get_item_duration (it) * fileinfo->fmt.samplerate * outch * output_bps / 8; } if (outsr != fileinfo->fmt.samplerate) { uint64_t temp = size; temp *= outsr; temp /= fileinfo->fmt.samplerate; size = temp; } memcpy (&wavehdr[22], &outch, 2); memcpy (&wavehdr[24], &outsr, 4); uint16_t blockalign = outch * output_bps / 8; memcpy (&wavehdr[32], &blockalign, 2); memcpy (&wavehdr[34], &output_bps, 2); fwrite (wavehdr, 1, wavehdr_size, temp_file); if (encoder_preset->method == DDB_ENCODER_METHOD_PIPE) { size = 0; } fwrite (&size, 1, sizeof (size), temp_file); header_written = 1; } int64_t res = fwrite (buffer, 1, sz, temp_file); if (sz != res) { fprintf (stderr, "converter: write error (%lld bytes written out of %d)\n", res, sz); goto error; } } if (abort && *abort) { goto error; } if (temp_file && temp_file != enc_pipe) { fseek (temp_file, wavehdr_size, SEEK_SET); fwrite (&outsize, 1, 4, temp_file); fclose (temp_file); temp_file = NULL; } if (encoder_preset->encoder[0] && encoder_preset->method == DDB_ENCODER_METHOD_FILE) { enc_pipe = popen (enc, "w"); } } } err = 0; error: if (temp_file && temp_file != enc_pipe) { fclose (temp_file); temp_file = NULL; } if (enc_pipe) { pclose (enc_pipe); enc_pipe = NULL; } if (dec && fileinfo) { dec->free (fileinfo); fileinfo = NULL; } if (abort && *abort && out[0]) { unlink (out); } if (input_file_name[0] && strcmp (input_file_name, "-")) { unlink (input_file_name); } // write junklib tags uint32_t tagflags = JUNK_STRIP_ID3V2 | JUNK_STRIP_APEV2 | JUNK_STRIP_ID3V1; if (encoder_preset->tag_id3v2) { tagflags |= JUNK_WRITE_ID3V2; } if (encoder_preset->tag_id3v1) { tagflags |= JUNK_WRITE_ID3V1; } if (encoder_preset->tag_apev2) { tagflags |= JUNK_WRITE_APEV2; } DB_playItem_t *out_it = deadbeef->pl_item_alloc (); deadbeef->pl_item_copy (out_it, it); deadbeef->pl_replace_meta (out_it, ":URI", out); deadbeef->pl_delete_meta (out_it, "cuesheet"); deadbeef->junk_rewrite_tags (out_it, tagflags, encoder_preset->id3v2_version + 3, "iso8859-1"); // write flac tags if (encoder_preset->tag_flac) { // find flac decoder plugin DB_decoder_t **plugs = deadbeef->plug_get_decoder_list (); DB_decoder_t *flac = NULL; for (int i = 0; plugs[i]; i++) { if (!strcmp (plugs[i]->plugin.id, "stdflac")) { flac = plugs[i]; break; } } if (!flac) { fprintf (stderr, "converter: flac plugin not found, cannot write flac metadata\n"); } else { if (0 != flac->write_metadata (out_it)) { fprintf (stderr, "converter: failed to write flac metadata, not a flac file?\n"); } } } // write vorbis tags if (encoder_preset->tag_oggvorbis) { // find flac decoder plugin DB_decoder_t **plugs = deadbeef->plug_get_decoder_list (); DB_decoder_t *ogg = NULL; for (int i = 0; plugs[i]; i++) { if (!strcmp (plugs[i]->plugin.id, "stdogg")) { ogg = plugs[i]; break; } } if (!ogg) { fprintf (stderr, "converter: ogg plugin not found, cannot write ogg metadata\n"); } else { if (0 != ogg->write_metadata (out_it)) { fprintf (stderr, "converter: failed to write ogg metadata, not an ogg file?\n"); } } } deadbeef->pl_item_unref (out_it); return err; }