void bond_xtal_origin_update (int iw) { register int i,j; int k; double *new_s, ds[3], tmp[3]; if (temporary_disable_bond) return; MALLOC( bond_xtal_origin_update, new_s, DIMENSION*np, double ); V3mM3 (n[iw].xtal_origin, HI, ds); V3TRIM (ds, ds); for (i=0; i<np; i++) { V3SUB ( &(s[DIMENSION*i]), ds, &(new_s[DIMENSION*i]) ); V3TriM ( &(new_s[DIMENSION*i]) ); } if (n[iw].bond_mode == BOND_MODE_USER) for (k=0; k<C->n_cylinders; k++) { i = CylinderAtoms[2*k]; j = CylinderAtoms[2*k+1]; V3SUB (&(new_s[DIMENSION*j]), &(new_s[DIMENSION*i]), tmp); if ( V3NEED_IMAGE(tmp) ) { /* g<0 means geometric invisibility */ C->CYLINDER[k].g = -fabs(C->CYLINDER[k].g); C->CYLINDER[k].radius = -fabs(C->CYLINDER[k].radius); } else { C->CYLINDER[k].g = fabs(C->CYLINDER[k].g); C->CYLINDER[k].radius = fabs(C->CYLINDER[k].radius); V3EQV (B->BALL[i].x, C->CYLINDER[k].x0); } } else for (i=0; i<np; i++) for (j=N->idx[i]; j<N->idx[i+1]; j++) { V3SUB (&(new_s[DIMENSION*N->list[j]]), &(new_s[DIMENSION*i]), tmp); if ( V3NEED_IMAGE(tmp) ) { /* g<0 means geometric invisibility */ C->CYLINDER[j].g = -fabs(C->CYLINDER[j].g); C->CYLINDER[j].radius = -fabs(C->CYLINDER[j].radius); } else { C->CYLINDER[j].g = BOND_G(i, N->list[j]); V3EQV (B->BALL[i].x, C->CYLINDER[j].x0); if (C->CYLINDER[j].r >= 0) C->CYLINDER[j].radius = n[iw].bond_radius; } } free (new_s); n[iw].bond_xtal_origin_need_update = FALSE; return; } /* end bond_xtal_origin_update() */
int Eyesight_Intersect_H_Box (int iw, int to_x, int to_y, double xx[3]) { register int i,j; int idx[6]; double k0, k1, s[6][3], x[6][3]; double z[6]; k0 = (to_x + 0.5 - AX_3D[iw].wx) / AX_3D[iw].k; k1 = (to_y + 0.5 - AX_3D[iw].wy) / AX_3D[iw].k; for (j=i=0; i<6; i++) if ( ((z[i]=Eyesight_Intersect_H_Surface (H, i, AX_3D[iw].x, AX_3D[iw].V, k0, k1, s[i], x[i])) > 0) && V3XIN(s[i],0,1) ) idx[j++] = i; if (j > 0) { qsort_numerical_recipes (j, z, idx, USE_OLD_IDX); V3EQV (x[idx[0]], xx); return (idx[0]); } else return (-1); } /* end Eyesight_Intersect_H_Box() */
/* Return z>0 if there is intersection, -1 otherwise. */ double Eyesight_Intersect_H_Surface (double H[3][3], int surface_id, double x0[3], double V[3][3], double k0, double k1, double s[3], double x[3]) { int i; double b[3], M[3][3], MI[3][3], tmp; i = surface_id / 2; if (surface_id % 2) V3SUB(x0,H[i],b); else V3EQV(x0,b); M3EQV(H,M); V3NEG(V[2],M[i]); V3SUBmuL(M[i],k0,V[0]); V3SUBmuL(M[i],k1,V[1]); tmp = M3DETERMINANT(M); if (ISTINY(tmp)) return(-1); M3INV(M,MI,tmp); V3mM3(b,MI,s); tmp = s[i]; s[i] = surface_id % 2; V3mM3 (s,H,x); return (tmp); } /* end Eyesight_Intersect_H_Surface() */
/* Allocate bonds */ void Config_to_3D_Bonds (double bond_radius) { register int i,j; AX_Float ds[3], DS[3]; AX_3D_Cylinders_Realloc (C, N->idx[np]); for (i=0; i<np; i++) for (j=N->idx[i]; j<N->idx[i+1]; j++) { V3EQV ( B->BALL[i].x, C->CYLINDER[j].x0 ); V3SUB ( &s[DIMENSION*N->list[j]], &s[DIMENSION*i], ds ); V3IMAGE ( ds, DS ); V3mM3 ( DS, H, C->CYLINDER[j].axis ); AX_V3NORMALIZE ( C->CYLINDER[j].axis, C->CYLINDER[j].axis[3] ); BONDCOLOR (i, N->list[j], j); if (V3NEED_IMAGE(ds)) { C->CYLINDER[j].g = -1; C->CYLINDER[j].radius = -1; } else C->CYLINDER[j].radius = bond_radius; } return; } /* end Config_to_3D_Bonds() */
void p3dp_s(double *si, int i, int irank) { if (p3d_rank(p3dp_cell) == irank) V3EQV(&s[DIMENSION*i], si); p3d_bcast(p3dp_cell, si, 3, MPI_DOUBLE, irank); }
bool print_status (int iw) { int i; double x[3], V[3][3]; SimpleStatistics ss; /* xterm_get_focus(iw); */ for (i=0; i<CONFIG_num_auxiliary; i++) { CalculateSimpleStatistics (np, CHARP(CONFIG_auxiliary[i]), sizeof(double), IOVAL_DOUBLE, &ss); printf("\nauxiliary[%d]=%s [%s], threshold=[%g, %g]\n", i, CONFIG_auxiliary_name[i], CONFIG_auxiliary_unit[i], n[iw].auxiliary_threshold[i][0], n[iw].auxiliary_threshold[i][1]); printf("[%g(%d), %g(%d)], avg=%g, std.dev.=%g\n", ss.min, ss.idx_min, ss.max, ss.idx_max, ss.average, ss.standard_deviation); } printf("\n======================= Status of Viewport #%d " "=======================\n",iw); V3EQV (AX_3D[iw].x, x); V3pr ("Viewpoint is at %M A,\n", x); M3inv (H, V); V3mM3 (AX_3D[iw].x, V, x); V3pr("in reduced coordinates it is %M;\n", x); M3EQV(AX_3D[iw].V, V); S3PR("viewport axes = %M;\n", V); printf ("window width = %d, height = %d pixels,\n", AX_size[iw].width, AX_size[iw].height); printf ("and conversion factor is %g pixel/radian,\n", AX_3D[iw].k); printf ("which converts to %g x %g degrees of field of view.\n", RADIAN_TO_DEGREE(2*atan(AX_size[iw].width/2/AX_3D[iw].k)), RADIAN_TO_DEGREE(2*atan(AX_size[iw].height/2/AX_3D[iw].k))); printf ("The viewport is now anchored to %s", (n[iw].anchor>=0)? "atom" : "hook" ); if (n[iw].anchor >= 0) print_atom(iw,n[iw].anchor); else { M3inv (H, V); V3mM3 (n[iw].hook, V, x); printf("\nx = [%g %g %g] A, or s = [%g %g %g].\n", n[iw].hook[0], n[iw].hook[1], n[iw].hook[2], x[0], x[1], x[2]); } printf("parallel projection mode is turned %s.\n", n[iw].parallel_projection?"ON":"OFF"); printf("term printout suppression is turned %s.\n", n[iw].suppress_printout?"ON":"OFF"); V3pr ("background color = %M.\n", n[iw].bgcolor); printf ("atom r_ratio = %f, bond radius = %f A.\n", n[iw].atom_r_ratio, n[iw].bond_radius); printf("bond mode is turned %s.\n", n[iw].bond_mode?"ON":"OFF"); printf("system average IS%s subtracted off from atomistic strains.\n", shear_strain_subtract_mean ? "" : "N'T"); printf("wireframe mode is %s.\n", (n[iw].wireframe_mode==WIREFRAME_MODE_CONTRAST)?"CONTRAST": (n[iw].wireframe_mode==WIREFRAME_MODE_NONE)?"NONE": (n[iw].wireframe_mode==WIREFRAME_MODE_RGBO)?"RGBO": (n[iw].wireframe_mode==WIREFRAME_MODE_RGBK)?"RGBK": (n[iw].wireframe_mode==WIREFRAME_MODE_RGB)?"RGB": "UNKNOWN"); if (n[iw].xtal_mode) { printf ("Xtal mode is turned ON:\n"); V3mM3 (n[iw].xtal_origin, HI, x); V3TRIM (x, x); V3pr ("xtal_origin = %M.\n", x); } else printf ("Xtal mode is turned OFF.\n"); printf ("color mode = %s.\n", (n[iw].color_mode==COLOR_MODE_NORMAL)? "NORMAL" : (n[iw].color_mode==COLOR_MODE_COORD)? "COORDINATION" : (n[iw].color_mode==COLOR_MODE_AUXILIARY)? "Auxiliary Properties" : (n[iw].color_mode==COLOR_MODE_SCRATCH)? "SCRATCH" : "UNKNOWN"); if (n[iw].shell_viewer_mode) printf("Shell viewer auto-invoke is turned ON.\n"); else printf("Shell viewer auto-invoke is turned OFF.\n"); printf("s[%d]=%d surface is now seen or selected.\n", n[iw].last_surface_id/2, n[iw].last_surface_id%2); if (rcut_patching) printf ("Neighbor distance cutoff between %s = %g.\n", rcut_patch_pairname, rcut_patch[rcut_patch_item].rcut); printf ("rate of change = %g.\n", n[iw].delta); if (n[iw].color_mode==COLOR_MODE_AUXILIARY) { i = n[iw].auxiliary_idx; if (i < CONFIG_num_auxiliary) printf("auxiliary[%d] = %s [%s], threshold = [%g, %g],\n", i, CONFIG_auxiliary_name[i], CONFIG_auxiliary_unit[i], n[iw].auxiliary_threshold[i][0], n[iw].auxiliary_threshold[i][1]); else printf("auxiliary = %s, threshold = [%g, %g],\n", geolist[i-CONFIG_MAX_AUXILIARY].token, n[iw].auxiliary_threshold[i][0], n[iw].auxiliary_threshold[i][1]); CalculateSimpleStatistics (np, CHARP(INW(n[iw].auxiliary_idx,CONFIG_num_auxiliary) ? CONFIG_auxiliary[i] : geo[i-CONFIG_MAX_AUXILIARY]), sizeof(double), IOVAL_DOUBLE, &ss); printf("[%g(%d),%g(%d)], avg=%g, std.dev.=%g,\n", ss.min, ss.idx_min, ss.max, ss.idx_max, ss.average, ss.standard_deviation); printf("auxiliaries' colormap = %s \"%s\".\n", AX_cmap_funs[n[iw].auxiliary_cmap].name, AX_cmap_funs[n[iw].auxiliary_cmap].description); printf("invisible outside auxiliary thresholds flag = %s.\n", n[iw].auxiliary_thresholds_saturation?"OFF":"ON"); printf("floating auxiliary thresholds flag = %s.\n", n[iw].auxiliary_thresholds_rigid?"OFF":"ON"); } printf ("clicked atoms = [ "); for (i=0; i<ATOM_STACK_SIZE; i++) printf ("%d ", n[iw].atom_stack[i]); printf ("];\n"); for (i=0; i<AX_3D_MAX_FILTER_PLANE; i++) if (AX_V3NEZERO(AX_3D[iw].fp[i].dx)) printf("%s fp %d: dx = [%g %g %g], s = [%g %g %g]\n", (n[iw].just_activated_fp==i) ? "*" : " ", i, V3E(AX_3D[iw].fp[i].dx), V3E(n[iw].fp[i].s0)); printf("==============================================" "=======================\n"); return(FALSE); } /* end print_status() */
/* Allocate arrows */ void Config_to_3D_Arrows(int arrow_idx, double scale_factor, double head_height, double head_width, double up[3], int overlay, double color[3]) { register int i, j, offset; double dx[3], head[3], head1[3], perp[3], perp2[3], sum; AX_3D_Lines tmp_arrows[1] = {{0}}; tmp_arrows[0].LINE = NULL; if (overlay) { offset = arrows->n_lines; if (offset != 0) { AX_3D_Lines_Realloc(tmp_arrows, arrows->n_lines); for (i=0; i<arrows->n_lines; i++) { V3EQV(arrows->LINE[i].x0, tmp_arrows->LINE[i].x0); V3EQV(arrows->LINE[i].x1, tmp_arrows->LINE[i].x1); AX_3D_AssignRGB (tmp_arrows->LINE[i], arrows->LINE[i].r, arrows->LINE[i].g, arrows->LINE[i].b); } } AX_3D_Lines_Realloc(arrows, arrows->n_lines + 3*np); if (offset != 0) { for (i=0; i<tmp_arrows->n_lines; i++) { V3EQV(tmp_arrows->LINE[i].x0, arrows->LINE[i].x0); V3EQV(tmp_arrows->LINE[i].x1, arrows->LINE[i].x1); AX_3D_AssignRGB (arrows->LINE[i], tmp_arrows->LINE[i].r, tmp_arrows->LINE[i].g, tmp_arrows->LINE[i].b); } AX_3D_Lines_Free(tmp_arrows); } } else { AX_3D_Lines_Realloc(arrows, 3*np); offset = 0; } /* auto scale */ if (scale_factor == 0.0) { sum = 0.0; for (i=0; i<np; i++) { dx[0] = *(CONFIG_auxiliary[arrow_idx+0]+i); dx[1] = *(CONFIG_auxiliary[arrow_idx+1]+i); dx[2] = *(CONFIG_auxiliary[arrow_idx+2]+i); sum += V3LENGTH(dx); } scale_factor = 1.0/(sum/np); printf("Config_to_3D_Arrows: average magnitude = %f, scale_factor set to %f\n", 1.0/scale_factor, scale_factor); } printf("Config_to_3D_Arrows: color = <%.3f,%.3f,%.3f>\n", color[0], color[1], color[2]); for (i=0; i<np; i++) { AX_3D_AssignRGB (arrows->LINE[offset+3*i], color[0], color[1], color[2]); AX_3D_AssignRGB (arrows->LINE[offset+3*i+1], color[0], color[1], color[2]); AX_3D_AssignRGB (arrows->LINE[offset+3*i+2], color[0], color[1], color[2]); dx[0] = *(CONFIG_auxiliary[arrow_idx+0]+i)*scale_factor; dx[1] = *(CONFIG_auxiliary[arrow_idx+1]+i)*scale_factor; dx[2] = *(CONFIG_auxiliary[arrow_idx+2]+i)*scale_factor; if (V3EQZERO(dx)) { for (j=0; j<3; j++) { V3EQV(B->BALL[i].x, arrows->LINE[offset+3*i+j].x0); V3EQV(B->BALL[i].x, arrows->LINE[offset+3*i+j].x1); } } else { V3ADD(B->BALL[i].x, dx, head); V3EQV(B->BALL[i].x, arrows->LINE[offset+3*i+0].x0); V3EQV(head, arrows->LINE[offset+3*i+0].x1); V3EQV(head, arrows->LINE[offset+3*i+1].x0); V3EQV(head, arrows->LINE[offset+3*i+2].x0); V3CROSS(dx, up, perp2); if (V3EQZERO(perp2)) { V3ASSIGN(1.0, 0.0, 0.0,perp); } else { V3CROSS(dx, perp2, perp); V3normalize(perp); } V3mul(head_width*V3LENGTH(dx),perp,perp); V3EQV(dx, head1); V3mul(head_height,head1,head1); V3SUB(head,head1,head1); V3ADD(head1,perp,arrows->LINE[offset+3*i+1].x1); V3SUB(head1,perp,arrows->LINE[offset+3*i+2].x1); } } }
/* Reload the configuration but keeping the rendering state */ void reload_config (int iw, bool term_input_filename) { register int i; int j, k, old_np; char fname[MAX_FILENAME_SIZE], oldfname[MAX_FILENAME_SIZE]; V3 hook_s, tmp, dx; char *old_symbol=NULL; bool incompatible_config; strcpy(oldfname, config_fname); if (n[iw].anchor >= 0) { /* the new configuration may not even have the atom */ V3EQV (B->BALL[n[iw].anchor].x, n[iw].hook); n[iw].anchor = -1; } /* hook_s[] is what is kept invariant */ V3mM3 (n[iw].hook, HI, hook_s); if (term_input_filename) { xterm_get_focus(iw); clear_stdin_buffer(); strcpy(fname,readline_gets("\nLoad configuration",config_fname)); strcpy(config_fname,fname); xterm_release_focus(iw); } if (!Fexists(config_fname)) { printf ("\n** %s: **\n", config_fname); printf ("** There is no such file! **\n"); strcpy(config_fname, oldfname); return; } if (!Freadable(config_fname)) { printf ("\n** %s: **\n", config_fname); printf ("** This file is unreadable! **\n"); strcpy(config_fname, oldfname); return; } cr(); old_np = np; CLONE(symbol, SYMBOL_SIZE*np, char, old_symbol); i = CONFIG_LOAD (config_fname, Config_Aapp_to_Alib); for (k=0; k<CONFIG_num_auxiliary; k++) if (*blank_advance(CONFIG_auxiliary_name[k])==EOS) sprintf(CONFIG_auxiliary_name[k], "auxiliary%d", k); rebind_CT (Config_Aapp_to_Alib, "", ct, &tp); cr(); Neighborlist_Recreate_Form (Config_Aapp_to_Alib, ct, N); if (i == CONFIG_CFG_LOADED) N->s_overflow_err_handler = NEIGHBORLIST_S_OVERFLOW_ERR_HANDLER_FOLD_INTO_PBC; else N->s_overflow_err_handler = NEIGHBORLIST_S_OVERFLOW_ERR_HANDLER_BOUNDING_BOX; N->small_cell_err_handler = NEIGHBORLIST_SMALL_CELL_ERR_HANDLER_MULTIPLY; for (i=0; i<ct->t; i++) for (j=i; j<ct->t; j++) for (k=0; k<rcut_patch_top; k++) if ( ( ( (rcut_patch[k].Zi == ct->Z[i]) && (rcut_patch[k].Zj == ct->Z[j]) ) || ( (rcut_patch[k].Zi == ct->Z[j]) && (rcut_patch[k].Zj == ct->Z[i]) ) ) ) NEIGHBOR_TABLE(N->rcut,ct,i,j) = NEIGHBOR_TABLE(N->rcut,ct,j,i) = rcut_patch[k].rcut; Neighborlist_Recreate (Config_Aapp_to_Alib, stdout, ct, &tp, N); V3mM3 (hook_s, H, tmp); V3SUB (tmp, n[iw].hook, dx); V3EQV (tmp, n[iw].hook); V3AdD (dx, AX_3D[iw].x); M3InV (H, HI, volume); lengthscale = cbrt(volume); V3ASSIGN (0.5,0.5,0.5,tmp); V3mM3 (tmp, H, cm); geo_clear_has_evaluated_flags(); evaluate_geo_measures(); Free(s1); Free(mass); if ( ComputeLeastSquareStrain ) { if (ConfigChecksum(Config_Aapp_to_Alib) != ref->checksum) printf ("This configuration is not isoatomic with the imprinted " "reference\n%s. Least-square strain NOT calculated.\n", ref_fbasename); else LeastSquareStrain_Append(); } incompatible_config = (np != old_np) || memcmp(symbol, old_symbol, SYMBOL_SIZE*MIN(np,old_np)); Free(old_symbol); if (incompatible_config) Config_to_3D_Balls (n[iw].atom_r_ratio); else for (i=0; i<np; i++) V3mM3 ( &(s[DIMENSION*i]), H, B->BALL[i].x ); atom_xtal_origin (n[iw].xtal_origin); if (!n[iw].auxiliary_thresholds_rigid) { for (i=0; i<CONFIG_num_auxiliary; i++) reset_auxiliary_threshold(iw,i); for (i=0; i<MAX_GEO_MEASURES; i++) if (geolist[i].has_evaluated) reset_auxiliary_threshold(iw,CONFIG_MAX_AUXILIARY+i); } if (!temporary_disable_bond) Config_to_3D_Bonds (n[iw].bond_radius); select_fbasename (config_fname); if ((n[iw].xtal_mode) && (n[iw].color_mode == COLOR_MODE_COORD)) assign_coordination_color(iw); else if (n[iw].color_mode == COLOR_MODE_AUXILIARY) color_encode_auxiliary(iw); else if (n[iw].color_mode == COLOR_MODE_SCRATCH) scratch_color (iw); else { strcpy (AX_title[iw],fbasename); AXSetName (iw); XStoreName(AX_display[iw],xterm_win,AX_title[iw]); XSetIconName(AX_display[iw],xterm_win,AX_title[iw]); if (!temporary_disable_bond) { bond_xtal_origin_update (iw); bond_atom_color_update (iw); } } return; } /* end reload_config() */