struct core_pak *copy_core(struct core_pak *core, struct model_pak *src, struct model_pak *dest) { gint items=0; gdouble vec[3]; struct core_pak *copyc; struct shel_pak *copys; /* checks */ g_assert(core != NULL); g_assert(src != NULL); g_assert(dest != NULL); /* duplicate data structure */ copyc = dup_core(core); items++; /* setup status */ copyc->status = copyc->status & (~SELECT & ~SELECT); copyc->orig = copyc->primary = TRUE; copyc->primary_core = NULL; VEC3SET(copyc->offset, 0.0, 0.0, 0.0); /* coords, account for transformation matrices */ ARR3SET(vec, core->rx); vecmat(dest->ilatmat, vec); ARR3ADD(vec, dest->centroid); ARR3SET(copyc->x, vec); dest->cores = g_slist_prepend(dest->cores, copyc); /* attached shell? */ if (copyc->shell) { copys = copyc->shell; items++; /* main info */ copys->status = copys->status & (~SELECT); copys->primary=copys->orig=TRUE; copys->primary_shell = NULL; VEC3SET(copys->offset, 0.0, 0.0, 0.0); /* coords, account for transformation matrices */ ARR3SET(vec, copys->rx); vecmat(dest->ilatmat, vec); ARR3ADD(vec, dest->centroid); ARR3SET(copys->x, vec); dest->shels = g_slist_prepend(dest->shels, copys); } return(copyc); }
void gui_siesta_mode_show(GtkWidget *w, gpointer dialog) { gint i, atom, state; gdouble scale, x1[3], x2[3], colour[3]; gpointer button, spin; GSList *list; struct core_pak *core; struct spatial_pak *spatial; struct model_pak *model; g_assert(dialog != NULL); model = dialog_model(dialog); g_assert(model != NULL); button = dialog_child_get(dialog, "phonon_toggle"); g_assert(button != NULL); spatial_destroy_by_label("siesta_phonons", model); state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); if (!state) { redraw_canvas(SINGLE); return; } spin = dialog_child_get(dialog, "phonon_scaling"); scale = SPIN_FVAL(spin); /* create & init the spatial object */ spatial = spatial_new("siesta_phonons", SPATIAL_VECTOR, 2, TRUE, model); atom = 0; /* get eigenvectors from all atoms */ for (list=model->cores ; list; list=g_slist_next(list)) { core = list->data; ARR3SET(x1, core->x); /* get current eigenvector */ i = model->siesta.sorted_eig_values[model->siesta.current_animation]; x2[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, i); x2[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, i); x2[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, i); atom++; /* compute coords */ VEC3MUL(x2, scale); vecmat(model->ilatmat, x2); ARR3ADD(x2, x1); /* add to spatial */ spatial_vertex_add(x2, colour, spatial); spatial_vertex_add(x1, colour, spatial); } /* drawing update */ coords_compute(model); redraw_canvas(SINGLE); }
void quat_rotate(gdouble *vec, gdouble *quat) { gdouble rot[9]; quat_matrix(rot, quat); vecmat(rot, vec); }
/* NB - this is siesta specific */ void zmat_coord_print(FILE *fp, GSList *species_list, gpointer data) { gint i, j; gdouble x[3]; GSList *list, *clist, *slist; struct model_pak *model=data; struct species_pak *species_data; struct core_pak *core; struct zmat_pak *zmat; g_assert(data != NULL); clist = g_slist_copy(model->cores); zmat = model->zmatrix; g_assert(zmat != NULL); for (list=zmat->zcores ; list ; list=g_slist_next(list)) clist = g_slist_remove(clist, list->data); j = 1 + g_slist_length(zmat->zcores); if (clist) { if (model->fractional) fprintf(fp, "fractional\n"); else fprintf(fp, "cartesian\n"); for (list=clist ; list ; list=g_slist_next(list)) { core = list->data; ARR3SET(x, core->x); /* NB: want fractional if 3D periodic, otherwise cartesian */ if (!model->fractional) vecmat(model->latmat, x); /* find corresponding number of this element in the species block */ i=1; for (slist=species_list ; slist ; slist=g_slist_next(slist)) { species_data = slist->data; if (g_ascii_strcasecmp(core->atom_label, species_data->label) == 0) break; i++; } fprintf(fp," %d %14.9f %14.9f %14.9f 1 1 1 %d\n", i, x[0], x[1], x[2], j++); } } g_slist_free(clist); }
gint write_dmol(gchar *filename, struct model_pak *model) { gint i; gdouble x[3]; GSList *list; struct core_pak *core; FILE *fp; /* checks */ g_return_val_if_fail(model != NULL, 1); g_return_val_if_fail(filename != NULL, 2); /* open the file */ fp = fopen(filename,"wt"); if (!fp) return(3); if (model->periodic == 3) { fprintf(fp, "$cell vectors\n"); /* NB: DMOL matrices are transposed wrt gdis */ for (i=0 ; i<3 ; i++) { fprintf(fp, " %20.14f%20.14f%20.14f\n", model->latmat[i]/AU2ANG, model->latmat[i+3]/AU2ANG, model->latmat[i+6]/AU2ANG); } } fprintf(fp, "$coordinates\n"); for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; if (core->status & DELETED) continue; /* everything is cartesian after latmat mult */ ARR3SET(x, core->x); vecmat(model->latmat, x); fprintf(fp,"%-10s%20.14f%20.14f%20.14f%5d\n", elements[core->atom_code].symbol, x[0]/AU2ANG, x[1]/AU2ANG, x[2]/AU2ANG, core->atom_code); } fprintf(fp, "$end\n"); fclose(fp); return(0); }
void trenchQFR(double *r,int *nn, double *z,int *nnz,double *EPSL,double *y,int *fault) { MATRIX b; VECTOR s,v; double logDet,_s,EPS; int i,n = *nn,nz = *nnz,_fault; if (n != nz) { for (i = 0; i < 2; i++) y[i] = 0.0; fault[0] = 3; return; } EPS = *EPSL; b = Matrix(n,n); v = Vector(n); _fault = trenchInv(r,n,b,v,EPS); if (_fault != 0) { for (i = 0; i < 2; i++) y[i] = 0.0; fault[0] = _fault; free_matrix(b); free_vector(v); return; } else fault[0] = 0; fromWedgeStorage(n,b); logDet = trenchDet(r,n,v); s = Vector (n); vecmat(n,z,b,s); _s = dot(n,s,z); y[0] = _s; y[1] = logDet; free_matrix(b); free_vector(v); free_vector(s); }
int main(int argc, char *argv[]) { int rank, nprocs, i, j; MPI_Status status; N = atoi(argv[1]); L = atoi(argv[2]); M = atoi(argv[3]); MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &rank); MPI_Comm_size(comm, &nprocs); if (rank == 0) { double a[N][L], b[L][M], c[N][M], tmp[M]; int count; FILE *fp =fopen("data", "r"); for (i = 0; i < N; i++) for (j = 0; j < L; j++) fscanf(fp,"%lf", &a[i][j]); for (i = 0; i < L; i++) for (j = 0; j < M; j++) fscanf(fp,"%lf",&b[i][j]); MPI_Bcast(b, L*M, MPI_DOUBLE, 0, comm); for (count = 0; count < nprocs-1 && count < N; count++) MPI_Send(&a[count][0], L, MPI_DOUBLE, count+1, count+1, comm); for (i = 0; i < N; i++) { MPI_Recv(tmp, M, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status); for (j = 0; j < M; j++) c[status.MPI_TAG-1][j] = tmp[j]; if (count < N) { MPI_Send(&a[count][0], L, MPI_DOUBLE, status.MPI_SOURCE, count+1, comm); count++; } } for (i = 1; i < nprocs; i++) MPI_Send(NULL, 0, MPI_INT, i, 0, comm); printMatrix(N, M, &c[0][0]); fclose(fp); } else { double b[L][M], in[L], out[M]; MPI_Bcast(b, L*M, MPI_DOUBLE, 0, comm); while (1) { MPI_Recv(in, L, MPI_DOUBLE, 0, MPI_ANY_TAG, comm, &status); if (status.MPI_TAG == 0) break; vecmat(in, b, out); MPI_Send(out, M, MPI_DOUBLE, 0, status.MPI_TAG, comm); } } MPI_Finalize(); return 0; }
void show_phonon_components(struct model_pak *model) { gdouble f, lc, lf, xc[3], xf[3]; gpointer ptr; GSList *list; struct core_pak *core; /* checks */ if (!model) return; /* get required mode to analyse */ ptr = g_slist_nth_data(model->phonons, model->current_phonon-1); if (!ptr) return; f = str_to_float(ptr); printf("--------------------------------------------------------------------------\n"); printf("Mode: %d, Frequency = %f\n", model->current_phonon, f); printf("--------------------------------------------------------------------------\n"); printf(" atom | len | x y z | a b c\n"); printf("--------------------------------------------------------------------------\n"); for (list=model->selection ; list; list=g_slist_next(list)) { core = (struct core_pak *) list->data; /* get eigen-vector components */ xc[0] = *((gdouble *) g_slist_nth_data(core->vibx_list, model->current_phonon-1)); xc[1] = *((gdouble *) g_slist_nth_data(core->viby_list, model->current_phonon-1)); xc[2] = *((gdouble *) g_slist_nth_data(core->vibz_list, model->current_phonon-1)); ARR3SET(xf, xc); vecmat(model->ilatmat, xf); lc = VEC3MAG(xc); lf = VEC3MAG(xf); VEC3MUL(xc, 1.0/lc); VEC3MUL(xf, 1.0/lf); printf("%6s | %7.4f | %7.2f %7.2f %7.2f | %7.2f %7.2f %7.2f\n", core->atom_label, lc, xc[0], xc[1], xc[2], xf[0], xf[1], xf[2]); } }
gint facet_equiv(struct model_pak *data, gint *f1, gint *f2) { gint i, index[3]; gdouble vec[3]; #if DEBUG_FACET_EQUIV printf("facet_equiv(): [%d %d %d] and (%d %d %d)\n", f1[0], f1[1], f1[2], f2[0], f2[1], f2[2]); #endif /* symmetry test */ if (data->sginfo.spacenum > 0) { for (i=0 ; i<data->sginfo.order ; i++) { ARR3SET(vec, f1); vecmat(*(data->sginfo.matrix+i), vec); ARR3SET(index, vec); #if DEBUG_FACET_EQUIV P3VEC("op -> ", vec); #endif if (index[0] == *f2 && index[1] == *(f2+1) && index[2] == *(f2+2)) { #if DEBUG_FACET_EQUIV printf(" *** equivalent (symop %d).\n", i); #endif return(TRUE); } } } else printf("No space group information.\n"); #if DEBUG_FACET_EQUIV printf("not equivalent.\n"); #endif return(FALSE); }
gint write_aims(gchar *filename, struct model_pak *model) { gint i; gdouble x[3]; GSList *list; struct core_pak *core; FILE *fp; /* checks */ g_return_val_if_fail(model != NULL, 1); g_return_val_if_fail(filename != NULL, 2); /* open the file */ fp = fopen(filename,"wt"); if (!fp) return(3); if (model->periodic == 3) { /* TODO: check whether lattice vectors in AIMS are transposed with respect GDIS */ for (i=0 ; i<3 ; i++) { fprintf(fp,"lattice_vector %14.8f %14.8f %14.8f \n", model->latmat[0+i], model->latmat[3+i], model->latmat[6+i]); } } for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; if (core->status & DELETED) continue; /* everything is cartesian after latmat mult */ ARR3SET(x, core->x); vecmat(model->latmat, x); fprintf(fp," atom %14.8f %14.8f %14.8f %3s \n", x[0], x[1], x[2], elements[core->atom_code].symbol); } fclose(fp); return(0); }
gint nwchem_input_export(gpointer import) { gint i, n; gdouble x[3]; gchar *text; gpointer config, value; GList *list, *keys; GSList *item; GString *buffer; struct model_pak *model; struct nwchem_pak *nwchem; struct core_pak *core; model = import_object_nth_get(IMPORT_MODEL, 0, import); if (!model) return(1); config = import_config_get(NWCHEM, import); if (!config) config = config_new(NWCHEM, NULL); //nwchem = import_config_data_get(NWCHEM, import); nwchem = config_data(config); if (!nwchem) { printf("Error: couldn't obtain an nwchem config.\n"); return(2); } buffer = g_string_new(NULL); g_string_append_printf(buffer, "#--- created by GDIS\n\n"); /* output start */ if (nwchem->start) g_string_append_printf(buffer, "%s\n", nwchem->start); /* output charge */ if (nwchem->charge) g_string_append_printf(buffer, "charge %s\n\n", nwchem->charge); /* output periodicity info */ switch (model->periodic) { case 3: g_string_append_printf(buffer, "system crystal\n"); g_string_append_printf(buffer, "lat_a %f lat_b %f lat_c %f\n", model->pbc[0], model->pbc[1], model->pbc[2]); g_string_append_printf(buffer, "alpha %f beta %f gamma %f\n", R2D*model->pbc[3], R2D*model->pbc[4], R2D*model->pbc[5]); g_string_append_printf(buffer, "end\n"); break; case 2: g_string_append_printf(buffer, "system surface\n"); g_string_append_printf(buffer, "lat_a %f lat_b %f\n", model->pbc[0], model->pbc[1]); g_string_append_printf(buffer, "gamma %f\n", R2D*model->pbc[5]); g_string_append_printf(buffer, "end\n"); break; case 1: g_string_append_printf(buffer, "system polymer\n"); g_string_append_printf(buffer, "lat_a %f\n", model->pbc[0]); g_string_append_printf(buffer, "end\n"); break; } /* output geometry */ g_string_append_printf(buffer, "geometry\n"); n = zmat_entries_get(model->zmatrix); if (n) { g_string_append_printf(buffer, " zmatrix\n"); text = zmatrix_connect_text(model->zmatrix); g_string_append(buffer, text); g_free(text); g_string_append_printf(buffer, " constants\n"); text = zmatrix_constants_text(model->zmatrix); g_string_append(buffer, text); g_free(text); g_string_append_printf(buffer, " variables\n"); text = zmatrix_variables_text(model->zmatrix); g_string_append(buffer, text); g_free(text); g_string_append_printf(buffer, " end\n"); } else { for (item=model->cores ; item ; item=g_slist_next(item)) { core = item->data; /* cartesian coords */ ARR3SET(x, core->x); vecmat(model->latmat, x); /* set fractional part */ for (i=0 ; i<model->periodic ; i++) if (model->fractional) x[i] = core->x[i]; /* from NWCHEM manual, coords are always fractional in periodic directions, else cartesian */ g_string_append_printf(buffer, "%s %f %f %f\n", core->atom_label, x[0], x[1], x[2]); } } g_string_append_printf(buffer, "end\n\n"); /* output basis library */ keys = g_hash_table_get_keys(nwchem->library); if (g_list_length(keys)) { g_string_append_printf(buffer, "basis\n"); for (list=keys ; list ; list=g_list_next(list)) { value = g_hash_table_lookup(nwchem->library, list->data); g_string_append_printf(buffer, "%s library %s\n", (gchar *) list->data, (gchar *) value); } g_string_append_printf(buffer, "end\n"); } /* unparsed */ // TODO - if it's just blank lines - skip text = config_unparsed_get(config); if (text) g_string_append_printf(buffer, "\n# --- unparsed start ---\n\n%s\n# --- unparsed stop ---\n\n", text); /* last item is the task to be performed */ /* CURRENT - some files may not have a task? */ if (nwchem->task_operation) { g_string_append_printf(buffer, "task"); if (nwchem->task_theory) g_string_append_printf(buffer, " %s", nwchem->task_theory); if (nwchem->task_operation) g_string_append_printf(buffer, " %s", nwchem->task_operation); } /* all done, write to disk or preview mode? */ if (import_preview_get(import)) { /* preview mode only */ import_preview_buffer_set(buffer->str, import); g_string_free(buffer, FALSE); } else { /* flush contents to disk */ g_file_set_contents(import_fullpath(import), buffer->str, -1, NULL); g_string_free(buffer, TRUE); } return(1); }
gint region_move_atom(struct core_pak *core, gint direction, struct model_pak *data) { gint flag, primary, secondary, mov[2]; gdouble vec[3], tmp[3], d[3]; GSList *list; struct core_pak *comp; #if DEBUG_REGION_SWITCH_ATOM printf(" model: %s\n", data->basename); printf(" periodicity: %d\n", data->periodic); printf(" hkl: %f %f %f\n", data->surface.miller[0], data->surface.miller[1], data->surface.miller[2]); printf(" dhkl: %f\n", data->surface.dspacing); printf("region sizes: %f %f\n", data->surface.region[0], data->surface.region[1]); printf(" moving: "); if (direction == UP) printf("UP\n"); else printf("DOWN\n"); #endif /* checks */ g_return_val_if_fail(data != NULL, 1); g_return_val_if_fail(data->periodic == 2, 1); if (data->surface.region[0] < 1) { gui_text_show(ERROR, "region 1 is empty.\n"); return(1); } /* setup region switching labels */ if (direction == UP) { primary = REGION1A; secondary = REGION2A; } else { primary = REGION2A; secondary = REGION1A; } /* get fractional depth translation vector */ ARR3SET(vec, data->surface.depth_vec); vecmat(data->ilatmat, vec); /* calculate offset to region boundary */ ARR3SET(tmp, vec); if (direction == DOWN) { VEC3MUL(tmp, data->surface.region[0]); VEC3MUL(tmp, -1.0); } else { if (data->surface.region[1] == 0) { VEC3MUL(tmp, data->surface.region[0]); } else { VEC3MUL(tmp, data->surface.region[1]); } } /* if region 2 is empty, just move core to the bottom */ if (data->surface.region[1] == 0.0) { ARR3ADD(core->x, tmp); if (core->shell) { ARR3ADD((core->shell)->x, tmp); } atom_colour_scheme(data->colour_scheme, core, data); return(0); } /* get coordinates of target atom */ ARR3ADD(tmp, core->x); #if DEBUG_REGION_SWITCH_ATOM P3VEC(" translation: ", vec); P3VEC(" target coords: ", tmp); #endif /* find the target */ flag=0; for (list=data->cores ; list ; list=g_slist_next(list)) { comp = list->data; /* only atoms of the same type need apply */ if (core->atom_code != comp->atom_code) continue; /* get difference vector */ ARR3SET(d, comp->x); ARR3SUB(d, tmp); /* pbc constraint */ while(d[0] < -FRACTION_TOLERANCE) d[0] += 1.0; while(d[0] > 0.5) d[0] -= 1.0; while(d[1] < -FRACTION_TOLERANCE) d[1] += 1.0; while(d[1] > 0.5) d[1] -= 1.0; /* test difference vector's magnitude */ if (VEC3MAGSQ(d) < FRACTION_TOLERANCE) { /* change its labelling */ #if DEBUG_REGION_SWITCH_ATOM printf("Matched core: %p\n", comp); #endif comp->region = secondary; if (comp->shell) { (comp->shell)->region = secondary; } atom_colour_scheme(data->colour_scheme, comp, data); flag++; break; } } if (!flag) { gui_text_show(ERROR, "Failed to find a boundary image.\n"); return(1); } /* now move selected atom to bottom of region 2 */ ARR3SET(tmp, vec); VEC3MUL(tmp, (data->surface.region[0] + data->surface.region[1])); if (direction == UP) VEC3MUL(tmp, -1.0); ARR3SUB(core->x, tmp); core->region = primary; /* pbc constrain */ fractional_clamp(core->x, mov, 2); if (core->shell) { ARR3SUB((core->shell)->x, tmp); ARR2ADD((core->shell)->x, mov); (core->shell)->region = primary; } atom_colour_scheme(data->colour_scheme, core, data); return(0); }
void camera_waypoint_animate(gint frames, gint overwrite, struct model_pak *model) { gint i; gdouble a, af, v[3], e[3], o[3], tmp[3]; gdouble jf, jv[3], x[3], mat[9]; GSList *list, *journey; struct camera_pak *cam, *cam1, *cam2; /* checks */ g_assert(model != NULL); g_assert(frames > 0); if (g_slist_length(model->waypoint_list) < 2) { gui_text_show(ERROR, "You need to make at least 2 waypoint.\n"); return; } /* close any active animation dialog */ dialog_destroy_type(ANIM); #if DEBUG_CAMERA_ANIMATE printf("frames for each traversal: %d\n", frames); #endif list = model->waypoint_list; cam1 = list->data; list = g_slist_next(list); /* create the camera journey */ journey = NULL; while (list) { cam2 = list->data; /* setup camera journey vector */ ARR3SET(jv, cam2->x); ARR3SUB(jv, cam1->x); /* add starting camera over journey leg */ for (i=0 ; i<frames ; i++) { /* journey fraction */ jf = i; jf /= frames; ARR3SET(x, jv); VEC3MUL(x, jf); cam = camera_dup(cam1); ARR3ADD(cam->x, x); journey = g_slist_prepend(journey, cam); } /* approx 5 degrees */ #define ROTATION_INCREMENT 0.08727 /* (v x e plane alignment) */ proj_vop(v, cam2->v, cam1->o); a = via(v, cam1->v, 3); /* compute rotation increment */ af = (gint) nearest_int(a / ROTATION_INCREMENT); if (!af) af = 1.0; /* test rotation sense */ matrix_v_rotation(mat, cam1->o, a); ARR3SET(tmp, cam1->v); vecmat(mat, tmp); if (via(tmp, v, 3) > 0.1) a *= -1.0; /* build rotaton */ matrix_v_rotation(mat, cam1->o, a/af); /* apply to camera */ ARR3SET(v, cam1->v); ARR3SET(e, cam1->e); for (i=af ; i-- ; ) { cam = camera_dup(cam1); ARR3SET(cam->x, cam2->x); vecmat(mat, v); vecmat(mat, e); ARR3SET(cam->v, v); ARR3SET(cam->e, e); journey = g_slist_prepend(journey, cam); } /* TODO - apply elevation to get v in complete coincidence */ /* rotate about e to achieve coincidence */ a = via(v, cam2->v, 3); /* compute rotation increment */ af = (gint) nearest_int(a / ROTATION_INCREMENT); if (!af) af = 1.0; /* test rotation sense */ matrix_v_rotation(mat, e, a); ARR3SET(tmp, v); vecmat(mat, tmp); if (via(tmp, cam2->v, 3) > 0.1) a *= -1.0; /* build rotaton */ matrix_v_rotation(mat, e, a/af); /* apply to camera */ ARR3SET(o, cam1->o); for (i=af ; i-- ; ) { cam = camera_dup(cam1); ARR3SET(cam->x, cam2->x); vecmat(mat, v); vecmat(mat, o); ARR3SET(cam->v, v); ARR3SET(cam->o, o); ARR3SET(cam->e, e); journey = g_slist_prepend(journey, cam); } /* endpoint camera */ journey = g_slist_prepend(journey, camera_dup(cam2)); /* get next journey leg */ cam1 = cam2; list = g_slist_next(list); } journey = g_slist_reverse(journey); if (overwrite) { free_slist(model->transform_list); model->transform_list = journey; } else model->transform_list = g_slist_concat(model->transform_list, journey); model->num_frames = g_slist_length(model->transform_list); model->animation = TRUE; redraw_canvas(SINGLE); }
gint write_gms(gchar *filename, struct model_pak *model) { gdouble x[3]; GSList *list; struct core_pak *core; FILE *fp; /* checks */ g_return_val_if_fail(model != NULL, 1); g_return_val_if_fail(filename != NULL, 2); /* open the file */ fp = fopen(filename,"wb"); if (!fp) return(3); /* TODO - enforce lines < 80 chars? */ /* print control keywords */ fprintf(fp, " $contrl coord=unique"); write_keyword(fp, GMS_EXETYPE_TXT, model->gamess.exe_type, exe_types); write_keyword(fp, GMS_SCFTYPE_TXT, model->gamess.scf_type, scf_types); write_keyword(fp, GMS_RUNTYPE_TXT, model->gamess.run_type, run_types); /* FIXME - put in to try & keep the lines below 80 chars */ fprintf(fp, "\n "); write_keyword(fp, GMS_UNITS_TXT, model->gamess.units, units); fprintf(fp, " %s%d", GMS_MAXIT_TXT, (gint) model->gamess.maxit); if (model->gamess.total_charge != 0.0) fprintf(fp, " %s%d", GMS_TOTAL_Q_TXT, (gint) model->gamess.total_charge); if (model->gamess.multiplicity > 1) fprintf(fp, " %s%d", GMS_MULT_TXT, (gint) model->gamess.multiplicity); if (model->gamess.wide_output) fprintf(fp, " %s6", GMS_WIDE_OUTPUT_TXT); fprintf(fp, " $end\n"); /* NEW - dft calc */ if (model->gamess.dft) { fprintf(fp, " $dft"); switch (model->gamess.dft_functional) { case SVWN: fprintf(fp, " dfttyp=SVWN"); break; case BLYP: fprintf(fp, " dfttyp=BLYP"); break; case B3LYP: fprintf(fp, " dfttyp=B3LYP"); break; } fprintf(fp, " $end\n"); } /* TODO: electron correlation stuff */ /* print size and memory */ fprintf(fp, " $system %s%d %s%d $end\x0a", GMS_TIMLIM_TXT, (gint) model->gamess.time_limit, GMS_MWORDS_TXT, (gint) model->gamess.mwords); /* print optimiser data */ if (model->gamess.run_type >= GMS_OPTIMIZE) { fprintf(fp, " $statpt %s%d ", GMS_NSTEP_TXT, (gint) model->gamess.nstep); write_keyword(fp, GMS_METHOD_TXT, model->gamess.opt_type, method_types); fprintf(fp, "$end\n"); } /* print basis set if one of the standard ones */ if (model->gamess.basis != GMS_USER) { fprintf(fp, " $basis "); write_keyword(fp, GMS_BASIS_TXT, model->gamess.basis, basis_types); if (model->gamess.ngauss) fprintf(fp, " %s%d", GMS_NGAUSS_TXT, model->gamess.ngauss); if (model->gamess.num_p) fprintf(fp, " %s%d", GMS_NUM_P_TXT, (gint) model->gamess.num_p); if (model->gamess.num_d) fprintf(fp, " %s%d", GMS_NUM_D_TXT, (gint) model->gamess.num_d); if (model->gamess.num_f) fprintf(fp, " %s%d", GMS_NUM_F_TXT, (gint) model->gamess.num_f); if (model->gamess.have_heavy_diffuse) fprintf(fp, " %s", GMS_DIFFSP_TXT); if (model->gamess.have_hydrogen_diffuse) fprintf(fp, " %s", GMS_DIFFS_TXT); fprintf(fp, " $end\n"); } /* print data */ fprintf(fp, " $DATA\n"); /* print data header */ fprintf(fp, "%s\n", model->gamess.title); /* print symmetry */ fprintf(fp, "c1\n"); for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; if (core->status & DELETED) continue; /* everything is cartesian after latmat mult */ ARR3SET(x, core->x); vecmat(model->latmat, x); if (model->gamess.units == GMS_ANGS) fprintf(fp,"%-7s %d %14.9f %14.9f %14.9f\n", elements[core->atom_code].symbol, elements[core->atom_code].number, x[0], x[1], x[2]); else fprintf(fp,"%-7s %d %14.9f %14.9f %14.9f\n", elements[core->atom_code].symbol, elements[core->atom_code].number, x[0]/BOHR_TO_ANGS, x[1]/BOHR_TO_ANGS, x[2]/BOHR_TO_ANGS); } fprintf(fp, " $END\n"); fclose(fp); return(0); }
gint write_cif(gchar *filename, struct model_pak *data) { gint flag=0; gdouble tmat[9], x[3], depth=1.0; GSList *list; FILE *fp; time_t t1; struct core_pak *core; /* init & checks */ g_return_val_if_fail(data != NULL, 1); fp = fopen(filename, "wt"); g_return_val_if_fail(fp != NULL, 2); /* is it a surface with negative z? */ if (data->periodic == 2) { if (g_slist_length(data->cores)) { core = g_slist_nth_data(data->cores, 0); if (core->x[2] < 0.0) flag++; } } /* rot to make z positive */ matrix_rotation(&tmat[0], PI, PITCH); t1 = time(NULL); fprintf(fp, "data_block_1\n"); fprintf(fp, "_audit_creation_date '%s'\n", g_strstrip(ctime(&t1))); fprintf(fp, "_audit_creation_method 'generated by GDIS v%4.2f'\n", VERSION); fprintf(fp, "\n\n"); if (data->periodic) { fprintf(fp, "_cell_length_a %8.4f\n",data->pbc[0]); fprintf(fp, "_cell_length_b %8.4f\n",data->pbc[1]); if (data->periodic == 2) { /* get depth info */ depth = (data->surface.region[0]+data->surface.region[1])*data->surface.depth; /* no depth info - make it large enough to fit everything */ if (depth < POSITION_TOLERANCE) depth = 2.0*data->rmax; fprintf(fp, "_cell_length_c %8.4f\n", depth); } else fprintf(fp, "_cell_length_c %8.4f\n",data->pbc[2]); fprintf(fp, "_cell_angle_alpha %8.2f\n",180.0*data->pbc[3]/PI); fprintf(fp, "_cell_angle_beta %8.2f\n",180.0*data->pbc[4]/PI); fprintf(fp, "_cell_angle_gamma %8.2f\n",180.0*data->pbc[5]/PI); fprintf(fp, "\n\n"); fprintf(fp, "_symmetry_space_group_name_H-M '%s'\n",data->sginfo.spacename); fprintf(fp, "_symmetry_Int_Tables_number %d\n",data->sginfo.spacenum); fprintf(fp, "\n\n"); } /* coords - format section */ fprintf(fp, "loop_\n"); fprintf(fp, "_atom_site_label\n"); if (data->periodic) { fprintf(fp, "_atom_site_fract_x\n"); fprintf(fp, "_atom_site_fract_y\n"); fprintf(fp, "_atom_site_fract_z\n"); } else { fprintf(fp, "_atom_site_cartn_x\n"); fprintf(fp, "_atom_site_cartn_y\n"); fprintf(fp, "_atom_site_cartn_z\n"); } /* coords - data section */ for (list=data->cores ; list ; list=g_slist_next(list)) { core = list->data; /* only the asymmetric cell if periodic */ if (data->periodic && !core->primary) continue; /* NB: want fractional if 3D periodic, otherwise cartesian */ ARR3SET(x, core->x); /* transformation needed? */ if (flag) vecmat(tmat, x); /* make the z coordinate "fractional" for a surface */ if (data->periodic == 2) x[2] /= depth; fprintf(fp, "%2s %10.6f %10.6f %10.6f\n", elements[core->atom_code].symbol, x[0], x[1], x[2]); } fprintf(fp, "\n\n"); fclose(fp); return(0); }
gint gui_phonon_loop(void) { gint current_phonon; gdouble f; gpointer ptr; GSList *list, *xlist, *ylist, *zlist; struct core_pak *core, *prim; struct model_pak *model; model = tree_model_get(); if (!model) return(FALSE); if (!model->animating) { gui_phonon_cleanup(model); return(FALSE); } //current_phonon = displayed_phonon; current_phonon = model->current_phonon; /* NB: list numbering starts from 0 */ ptr = g_slist_nth_data(model->phonons, current_phonon-1); if (!ptr) { #if DEBUG_PHONON_LOOP printf("Bad phonon %d/%d\n", current_phonon, g_slist_length(model->phonons)); #endif gui_phonon_cleanup(model); return(FALSE); } if (!model->pulse_direction) { gui_phonon_cleanup(model); return(FALSE); } /* setup scaling for this step */ model->pulse_count += model->pulse_direction; if (model->pulse_count <= -sysenv.render.phonon_resolution) { model->pulse_count = -sysenv.render.phonon_resolution; model->pulse_direction = 1; } if (model->pulse_count >= sysenv.render.phonon_resolution) { model->pulse_count = sysenv.render.phonon_resolution; model->pulse_direction = -1; } f = sysenv.render.phonon_scaling; f *= (gdouble) model->pulse_count; f /= sysenv.render.phonon_resolution; /* get eigenvectors from all atoms */ for (list=model->cores ; list; list=g_slist_next(list)) { core = list->data; /* get eigenvector list */ if (core->primary) { xlist = core->vibx_list; ylist = core->viby_list; zlist = core->vibz_list; } else { prim = core->primary_core; xlist = prim->vibx_list; ylist = prim->viby_list; zlist = prim->vibz_list; } g_assert(xlist != NULL); g_assert(ylist != NULL); g_assert(zlist != NULL); /* vibrational eigenvector */ ptr = g_slist_nth_data(xlist, current_phonon-1); if (!ptr) { gui_phonon_cleanup(model); return(FALSE); } core->offset[0] = *((gdouble *) ptr); ptr = g_slist_nth_data(ylist, current_phonon-1); if (!ptr) { gui_phonon_cleanup(model); return(FALSE); } core->offset[1] = *((gdouble *) ptr); ptr = g_slist_nth_data(zlist, current_phonon-1); if (!ptr) { gui_phonon_cleanup(model); return(FALSE); } core->offset[2] = *((gdouble *) ptr); /* pulse offset scaling */ VEC3MUL(core->offset, f); vecmat(model->ilatmat, core->offset); /* TODO - shell also? */ } /* recalc coords and adjust bond orientations */ coords_compute(model); connect_midpoints(model); redraw_canvas(SINGLE); return(TRUE); }
// not really an animate function as such... void gui_animate_phonon_vectors(struct model_pak *model) { gdouble *v, x1[3], x2[3], colour[3]; gpointer spatial, ptr; GSList *list, *xlist, *ylist, *zlist; struct core_pak *core, *prim; if (!model) return; /* create & init the spatial object */ spatial_destroy_by_label("phonons", model); spatial = spatial_new("phonons", SPATIAL_VECTOR, 2, TRUE, model); /* get eigenvectors from all atoms */ for (list=model->cores ; list; list=g_slist_next(list)) { core = list->data; ARR3SET(x1, core->x); /* get eigenvector list */ if (core->primary) { xlist = core->vibx_list; ylist = core->viby_list; zlist = core->vibz_list; } else { prim = core->primary_core; xlist = prim->vibx_list; ylist = prim->viby_list; zlist = prim->vibz_list; } if (!xlist || !ylist || !zlist) { printf("Missing phonon eigenvectors.\n"); return; } /* vibrational eigenvector */ /* NB: current_phonon starts from 1 */ ptr = g_slist_nth_data(xlist, model->current_phonon-1); if (ptr) x2[0] = *((gdouble *) ptr); ptr = g_slist_nth_data(ylist, model->current_phonon-1); if (ptr) x2[1] = *((gdouble *) ptr); v = g_slist_nth_data(zlist, model->current_phonon-1); if (ptr) x2[2] = *v; /* pulse offset scaling */ VEC3MUL(x2, sysenv.render.phonon_scaling); vecmat(model->ilatmat, x2); /* TODO - unify with siesta */ /* i = model->siesta.sorted_eig_values[model->siesta.current_animation]; x2[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, i); x2[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, i); x2[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, i); atom++; */ /* compute coords */ ARR3ADD(x2, x1); /* add to spatial */ spatial_vertex_add(x2, colour, spatial); spatial_vertex_add(x1, colour, spatial); } coords_compute(model); gui_refresh(GUI_CANVAS); }
gint write_xml(gchar *filename, struct model_pak *model) { gdouble vec[3]; GSList *list, *list2; struct core_pak *core; struct vec_pak *v; struct spatial_pak *spatial; FILE *fp; fp = fopen(filename, "wt"); if (!fp) return(1); fprintf(fp, "<system>\n"); /* periodicity */ if (model->periodic) { switch (model->periodic) { case 1: fprintf(fp, " <crystal dictRef=\"gulp:polymer\">\n"); break; case 2: fprintf(fp, " <crystal dictRef=\"gulp:surface\">\n"); break; default: fprintf(fp, " <crystal dictRef=\"gulp:fullcell\">\n"); break; } fprintf(fp, " <cell dictRef=\"cml:a\"> %f </cell>\n", model->pbc[0]); fprintf(fp, " <cell dictRef=\"cml:b\"> %f </cell>\n", model->pbc[1]); fprintf(fp, " <cell dictRef=\"cml:c\"> %f </cell>\n", model->pbc[2]); fprintf(fp, " <cell dictRef=\"cml:alpha\"> %f </cell>\n", R2D*model->pbc[3]); fprintf(fp, " <cell dictRef=\"cml:beta\"> %f </cell>\n", R2D*model->pbc[4]); fprintf(fp, " <cell dictRef=\"cml:gamma\"> %f </cell>\n", R2D*model->pbc[5]); fprintf(fp, " </crystal>\n"); } /* cores */ for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; ARR3SET(vec, core->x); vecmat(model->latmat, vec); /* fprintf(fp, " <atom elementType=\"%s\" x3=\"%f\" y3=\"%f\" z3=\"%f\">", core->atom_label, vec[0], vec[1], vec[2]); */ fprintf(fp, " <atom elementType=\"%s\" x3=\"%f\" y3=\"%f\" z3=\"%f\">", elements[core->atom_code].symbol, vec[0], vec[1], vec[2]); fprintf(fp, "</atom>\n"); /* TODO - shells as particles */ } /* spatial data */ for (list=model->spatial ; list ; list=g_slist_next(list)) { spatial = list->data; fprintf(fp, "<spatial Method=\"%d\" Periodic=\"%d\">\n", spatial->method, spatial->periodic); for (list2=spatial->list ; list2 ; list2=g_slist_next(list2)) { v = list2->data; fprintf(fp, " <vertex red=\"%f\" green=\"%f\" blue=\"%f\"", v->colour[0], v->colour[1], v->colour[2]); fprintf(fp, " x3=\"%f\" y3=\"%f\" z3=\"%f\"", v->x[0], v->x[1], v->x[2]); fprintf(fp, " nx=\"%f\" ny=\"%f\" nz=\"%f\"></vertex>\n", v->n[0], v->n[1], v->n[2]); } fprintf(fp, "</spatial>\n"); } /* camera waypoints */ for (list=model->waypoint_list ; list ; list=g_slist_next(list)) { struct camera_pak *camera = list->data; fprintf(fp, "<waypoint mode=\"%d\" perspective=\"%d\" fov=\"%f\" zoom=\"%f\"\n", camera->mode, camera->perspective, camera->fov, camera->zoom); fprintf(fp, "x0=\"%f\" x1=\"%f\" x2=\"%f\"\n",camera->x[0],camera->x[1],camera->x[2]); fprintf(fp, "o0=\"%f\" o1=\"%f\" o2=\"%f\"\n",camera->o[0],camera->o[1],camera->o[2]); fprintf(fp, "v0=\"%f\" v1=\"%f\" v2=\"%f\"\n",camera->v[0],camera->v[1],camera->v[2]); fprintf(fp, "e0=\"%f\" e1=\"%f\" e2=\"%f\"\n",camera->e[0],camera->e[1],camera->e[2]); fprintf(fp, "q0=\"%f\" q1=\"%f\" q2=\"%f\" q3=\"%f\">", camera->q[0], camera->q[1], camera->q[2], camera->q[3]); fprintf(fp, "</waypoint>\n"); } fprintf(fp, "</system>\n"); fclose(fp); return(0); }
gint write_gromacs_gro(gchar *filename, struct model_pak *model) { gint n, c, i, s; gdouble x[3], min[3], max[3]; GSList *list; struct core_pak *core; FILE *fp; fp = fopen(filename, "wt"); if (!fp) return(1); /* init min/max for box calculation */ for (i=3 ; i-- ; ) { max[i] = -G_MAXDOUBLE; min[i] = G_MAXDOUBLE; } fprintf(fp, "GROMACS coordinates (generated by GDIS v%f)\n", VERSION); c = g_slist_length(model->cores); s = g_slist_length(model->shels); fprintf(fp, "%5d\n", c+s); n = 1; for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; /* cartesians */ ARR3SET(x, core->x); vecmat(model->latmat, x); /* angs -> nm */ VEC3MUL(x, 0.1); fprintf(fp, "%5i%5s%5s%5i%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f\n", n, "UNK", core->atom_label, 1, x[0], x[1], x[2], 0.1*core->v[0], 0.1*core->v[1], 0.1*core->v[2]); /* record min/max for box calculation */ for (i=3 ; i-- ; ) { if (x[i] < min[i]) min[i] = x[i]; if (x[i] > max[i]) max[i] = x[i]; } if (core->shell) { /* TODO - has an 'x' post-fix to the atom_label */ } n++; } /* this is the distance between the min and max atom coords in x, y, and z */ /* box calculation */ if (model->periodic == 3) { fprintf(fp, "% f %f %f\n", 0.1*model->pbc[0], 0.1*model->pbc[1], 0.1*model->pbc[2]); } else { for (i=0 ; i<3 ; i++) fprintf(fp, " %f", fabs(max[i] - min[i])); fprintf(fp, "\n"); } fclose(fp); return(0); }
gint surf_sysabs(struct model_pak *data, gint h, gint k, gint l) { gint i, flag; gint f1[3] /*, f2[3]*/; gdouble dp, dummy, vec[3], df[3]; #if DEBUG_FACET_ABSENT printf("testing %d %d %d\n", h, k, l); #endif /* apply the symmetry matrices (skip identity) */ VEC3SET(f1, h, k, l); for (i=1 ; i<data->sginfo.order ; i++) { /* NEW - identity + translation alone is insufficent */ if (matrix_is_identity(*(data->sginfo.matrix+i))) continue; VEC3SET(vec, h, k, l); vecmat(*(data->sginfo.matrix+i), vec); flag = 0; /* not needed - we've expanded all symmetry operations (incl. inversion) */ /* test f1 . m = -f1 */ /* ARR3SET(df, f1); ARR3ADD(df, vec); if (VEC3MAGSQ(df) < FRACTION_TOLERANCE) if (data->sginfo.inversion) flag++; */ /* test f1 . m = f1 */ ARR3SET(df, f1); ARR3SUB(df, vec); if (VEC3MAGSQ(df) < POSITION_TOLERANCE) flag++; if (flag) { #if DEBUG_FACET_ABSENT printf("symop [%d] satisfies 1st absence condition.\n", i); P3MAT("matrix:", *(data->sginfo.matrix+i)); P3VEC("offset:", *(data->sginfo.offset+i)); #endif /* test if <f1,t> = non-integer */ ARR3SET(vec, *(data->sginfo.offset+i)); ARR3MUL(vec, f1); dp = fabs(vec[0] + vec[1] + vec[2]); if (modf(dp, &dummy) > POSITION_TOLERANCE) { #if DEBUG_FACET_ABSENT printf("symop [%d] [%f %f %f] satisfies 2nd absence condition.\n", i, *(*(data->sginfo.offset+i)+0), *(*(data->sginfo.offset+i)+1), *(*(data->sginfo.offset+i)+2)); printf("facet is extinct.\n"); #endif return(TRUE); } } } #if DEBUG_FACET_ABSENT printf(">>> Not absent\n"); #endif return(FALSE); }
void zmat_process(gpointer data, struct model_pak *model) { gint i, n; gdouble r, a, d; gdouble v1[3], v2[3], v3[3], m1[9], m2[9]; gpointer tmp; GSList *list; struct zmat_pak *zmat = data; struct zval_pak *zval; struct core_pak *core[4] = {NULL, NULL, NULL, NULL}; /* checks */ if (!zmat) return; matrix_lattice_init(model); #if ZMAT_PROCESS_DEBUG printf("distance scale = %f\n", zmat->distance_scale); printf("angle scale = %f\n", zmat->angle_scale); #endif /* track the core # - 1st 3 items in zmatrix are exceptions */ n = 0; for (list=zmat->zlines ; list ; list=g_slist_next(list)) { zval = list->data; /* check for variable names */ for (i=3 ; i-- ; ) { if (zval->name[i]) { /* hash table lookup for variable value */ zval->value[i] = zmat_table_lookup(zval->name[i], zmat); } } /* create the core */ #if ZMAT_PROCESS_DEBUG printf("[%d = %s] [%d %d %d]", zval->type, zval->elem, zval->connect[0], zval->connect[1], zval->connect[2]); P3VEC(" x: ", zval->value); #endif /* TODO - need to mark zmatrix generated cores as special */ /* probably have another list in the zmat struct that contains */ /* all the cores created below */ switch (n) { case 0: /* TODO - convert to cartesian if fractional and enforce cart model */ core[0] = new_core(zval->elem, model); model->cores = g_slist_prepend(model->cores, core[0]); zmat->zcores = g_slist_prepend(zmat->zcores, core[0]); ARR3SET(core[0]->x, zval->value); if (zmat->fractional) vecmat(model->latmat, core[0]->x); else { VEC3MUL(core[0]->x, zmat->distance_scale); } break; case 1: core[1] = new_core(zval->elem, model); model->cores = g_slist_prepend(model->cores, core[1]); zmat->zcores = g_slist_prepend(zmat->zcores, core[1]); r = zmat->distance_scale * zval->value[0]; /* a = zmat->angle_scale * zval->value[1]; d = zmat->angle_scale * zval->value[2]; */ /* SIESTA hack : z-axis angle is 2nd, and theta is 3rd (last) */ a = zmat->angle_scale * zval->value[2]; d = zmat->angle_scale * zval->value[1]; v1[0] = v1[1] = r * sin(d); v1[0] *= cos(a); v1[1] *= sin(a); v1[2] = r * cos(d); ARR3SET(core[1]->x, core[0]->x); ARR3ADD(core[1]->x, v1); break; case 2: /* check the connection order */ if (zval->connect[0] == 2) { tmp = core[0]; core[0] = core[1]; core[1] = tmp; } r = zmat->distance_scale * zval->value[0]; a = zmat->angle_scale * zval->value[1]; d = zmat->angle_scale * zval->value[2]; ARR3SET(v2, core[1]->x); ARR3SUB(v2, core[0]->x); /* get rotation axis for bond angle */ VEC3SET(v3, 0.0, 0.0, 1.0); crossprod(v1, v3, v2); /* rotate bondlength scaled vector into position */ matrix_v_rotation(m2, v1, a); ARR3SET(v3, v2); normalize(v3, 3); VEC3MUL(v3, r); vecmat(m2, v3); /* rotate to give required dihedral */ matrix_v_rotation(m1, v2, d); vecmat(m1, v3); /* generate the atom position */ core[2] = new_core(zval->elem, model); model->cores = g_slist_prepend(model->cores, core[2]); zmat->zcores = g_slist_prepend(zmat->zcores, core[2]); ARR3SET(core[2]->x, core[0]->x); ARR3ADD(core[2]->x, v3); break; default: /* get core connectivity (NB: prepending cores - hence n - number) */ core[0] = g_slist_nth_data(zmat->zcores, n-zval->connect[0]); core[1] = g_slist_nth_data(zmat->zcores, n-zval->connect[1]); core[2] = g_slist_nth_data(zmat->zcores, n-zval->connect[2]); g_assert(core[0] != NULL); g_assert(core[1] != NULL); g_assert(core[2] != NULL); r = zmat->distance_scale * zval->value[0]; a = zmat->angle_scale * zval->value[1]; d = zmat->angle_scale * zval->value[2]; /* setup vectors */ ARR3SET(v2, core[1]->x); ARR3SUB(v2, core[0]->x); ARR3SET(v3, core[2]->x); ARR3SUB(v3, core[1]->x); /* rotate v3 about v2 to give dihedral */ matrix_v_rotation(m1, v2, d); vecmat(m1, v3); /* get rotation axis and matrix for bond angle */ crossprod(v1, v3, v2); matrix_v_rotation(m2, v1, a); normalize(v2, 3); VEC3MUL(v2, r); vecmat(m2, v2); /* generate the atom position */ core[3] = new_core(zval->elem, model); model->cores = g_slist_prepend(model->cores, core[3]); zmat->zcores = g_slist_prepend(zmat->zcores, core[3]); ARR3SET(core[3]->x, core[0]->x); ARR3ADD(core[3]->x, v2); /* TODO (maybe) - some zmatrix constructions implicitly assume */ /* some checking for duplicate atoms & reversing the torsional */ /* angle sense to accomodate this. */ break; } n++; } /* zmatrix cores are created in cartesians - revert to fractional if required */ if (model->fractional) { for (list=zmat->zcores ; list ; list=g_slist_next(list)) { core[0] = list->data; vecmat(model->ilatmat, core[0]->x); } } }
void zmat_build(void) { gint i, j, k, n, type; gdouble r, a, d, x[4][3], v[3]; gdouble zaxis[3] = {0.0, 0.0, 1.0}; gchar *line; GSList *list, *species; struct zmat_pak *zmat; struct core_pak *core[4] = {NULL, NULL, NULL, NULL}; struct model_pak *model; model = sysenv.active_model; if (!model) return; /* CURRENT - using selection as our list of cores to generate a zmatrix from */ if (!model->selection) { gui_text_show(WARNING, "ZMATRIX: please select a molecule.\n"); return; } /* destroy old zmatrix */ /* TODO - prompt if non null */ zmat_free(model->zmatrix); zmat = model->zmatrix = zmat_new(); zmat_angle_units_set(model->zmatrix, DEGREES); /* setup SIESTA species type */ species = fdf_species_build(model); /* sort the list so it follows molecular connectivity */ model->selection = zmat_connect_sort(model->selection); n=0; for (list=model->selection ; list ; list=g_slist_next(list)) { /* current atom/zmatrix line init */ core[0] = list->data; type = fdf_species_index(core[0]->atom_label, species); line = NULL; zmat->zcores = g_slist_append(zmat->zcores, core[0]); /* build a ZMATRIX line for processing */ switch (n) { case 0: if (core[0]) { ARR3SET(x[0], core[0]->x); vecmat(model->latmat, x[0]); } line = g_strdup_printf("%d 0 0 0 %f %f %f 0 0 0\n", type, x[0][0], x[0][1], x[0][2]); break; case 1: if (core[0]) { ARR3SET(x[0], core[0]->x); vecmat(model->latmat, x[0]); } if (core[1]) { ARR3SET(x[1], core[1]->x); vecmat(model->latmat, x[1]); } r = measure_distance(x[0], x[1]); /* angle with z axis */ ARR3SET(v, x[0]); ARR3SUB(v, x[1]); a = R2D * via(v, zaxis, 3); /* angle between xy projection and x axis */ d = R2D * angle_x_compute(v[0], v[1]); line = g_strdup_printf("%d 1 0 0 %f %f %f 0 0 0\n", type, r, a, d); break; case 2: /* coords init */ for (i=3 ; i-- ; ) { if (core[i]) { ARR3SET(x[i], core[i]->x); vecmat(model->latmat, x[i]); } else g_assert_not_reached(); } r = measure_distance(x[0], x[1]); a = measure_angle(x[0], x[1], x[2]); /* create a fake core -> 1 unit displaced in the z direction */ g_assert(core[3] == NULL); core[3] = core_new("x", NULL, model); ARR3SET(core[3]->rx, core[2]->rx); ARR3ADD(core[3]->rx, zaxis); d = measure_torsion(core); core_free(core[3]); line = g_strdup_printf("%d 2 1 0 %f %f %f 0 0 0\n", type,r,a,d); break; default: /* connectivity test */ if (!zmat_bond_check(core[0], core[1])) { #if DEBUG_ZMAT_BUILD printf("[%d] non-connected atoms [%f]\n", n, measure_distance(x[0], x[1])); #endif /* need to build a new connectivity chain starting from core[0] */ core[1] = core[2] = core[3] = NULL; if (!zmat_connect_find(n, core, zmat)) { gui_text_show(WARNING, "ZMATRIX: bad connectivity (molecule will be incomplete)\n"); goto zmat_build_done; } } /* coords init */ for (i=3 ; i-- ; ) { if (core[i]) { ARR3SET(x[i], core[i]->x); vecmat(model->latmat, x[i]); } else g_assert_not_reached(); } r = measure_distance(x[0], x[1]); a = measure_angle(x[0], x[1], x[2]); d = measure_torsion(core); /* NB: indexing starts from 0, siesta starts from 1 (naturally) */ i = 1+g_slist_index(zmat->zcores, core[1]); j = 1+g_slist_index(zmat->zcores, core[2]); k = 1+g_slist_index(zmat->zcores, core[3]); line = g_strdup_printf("%d %d %d %d %f %f %f 0 0 0\n", type,i,j,k,r,a,d); } /* process a successfully constructed ZMATRIX line */ if (line) { zmat_core_add(line, model->zmatrix); g_free(line); } /* shuffle */ core[3] = core[2]; core[2] = core[1]; core[1] = core[0]; n++; } zmat_build_done: /* do the species typing */ zmat_type(model->zmatrix, species); free_slist(species); }
void docking_project_create(GtkWidget *w, struct model_pak *model) { gint a, b, i, m, n, rx, ry, rz, size, rigid_save; gint a_max, b_max, rx_max, ry_max, rz_max; gchar *file, *dump, *dump_save, *rigid_move_save; gdouble dx, dy, dz, x[3], scale[3], mat[9], dock_centroid[3], q[4]; GString *name, *rigid; GSList *list, *core_list, *shell_list; struct dock_pak *dock; struct core_pak *core, *core2; struct shel_pak *shell, *shell2; FILE *fp; /* checks */ g_assert(model != NULL); size = g_slist_length(model->selection); if (!size) { gui_text_show(WARNING, "Please select the subset you wish to dock.\n"); return; } /* create new docking project */ dock = g_malloc(sizeof(struct dock_pak)); /* NEW - setup project path */ /* g_path_get_dirname(model->fullpath); g_get_current_dir(); */ /* seek a file name that doesn't exist (avoid background overwriting) */ name = g_string_new(NULL); i=0; do { g_string_sprintf(name, "project_%06d", i); i++; } while (g_file_test(name->str, G_FILE_TEST_EXISTS)); dock->path = g_build_path(sysenv.cwd, name->str, NULL); printf("creating new project: [%s]\n", dock->path); #if WIN32 if (mkdir(dock->path)) #else if (mkdir(dock->path, 0700)) #endif { gui_text_show(ERROR, "Failed to create project directory.\n"); g_free(dock->path); g_free(dock); return; } /* project control file */ g_string_sprintf(name, "%s%sproject.pcf", dock->path, DIR_SEP); fp = fopen(name->str, "wt"); /* save original variables */ dump_save = model->gulp.dump_file; model->gulp.dump_file = NULL; rigid_save = model->gulp.rigid; model->gulp.rigid = dock_rigid_on; rigid_move_save = model->gulp.rigid_move; model->gulp.rigid_move = NULL; if (model->gulp.rigid) { rigid = g_string_new(NULL); if (dock_rigid_x) g_string_sprintf(rigid, "x"); if (dock_rigid_y) g_string_sprintfa(rigid, "y"); if (dock_rigid_z) g_string_sprintfa(rigid, "z"); model->gulp.rigid_move = g_string_free(rigid, FALSE); } /* duplicate selection for docking */ core_list = NULL; shell_list = NULL; VEC3SET(dock_centroid, 0.0, 0.0, 0.0); for (list=model->selection ; list ; list=g_slist_next(list)) { core2 = dup_core(list->data); core_list = g_slist_prepend(core_list, core2); if (core2->shell) shell_list = g_slist_prepend(shell_list, core2->shell); /* compute centroid */ ARR3ADD(dock_centroid, core2->x); } /* NB: lists must have the same order as original selection */ core_list = g_slist_reverse(core_list); shell_list = g_slist_reverse(shell_list); VEC3MUL(dock_centroid, 1.0/(gdouble) size); /* fractional translation grid units */ scale[0] = dock_cell[0] / dock_grid[0]; scale[1] = dock_cell[1] / dock_grid[1]; /* rotational increments */ dx = PI/dock_rotate[0]; dy = PI/dock_rotate[1]; dz = PI/dock_rotate[2]; /* translational sampling */ if (dock_grid_on) { a_max = dock_grid[0]; b_max = dock_grid[1]; } else { a_max = 1; b_max = 1; } /* rotational sampling */ if (dock_rotate_on) { rx_max = dock_rotate[0]; ry_max = dock_rotate[1]; rz_max = dock_rotate[2]; } else { rx_max = 1; ry_max = 1; rz_max = 1; } /* project header */ fprintf(fp, "%%title solvent mapping project\n"); fprintf(fp, "%%set %d %d %f %f\n", a_max, b_max, dock_cell[0], dock_cell[1]); /* loop over all grid translations */ m = n = 0; for (a=0 ; a<a_max ; a++) { for (b=0 ; b<b_max ; b++) { VEC3SET(x, a, b, 0.0); x[0] *= scale[0]; x[1] *= scale[1]; /* loop over rotations */ VEC4SET(q, 1.0, 0.0, 0.0, 0.0); for (rx=0 ; rx<rx_max ; rx++) { if (rx) quat_concat_euler(q, PITCH, dx); for (ry=0 ; ry<ry_max ; ry++) { if (ry) quat_concat_euler(q, ROLL, dy); for (rz=0 ; rz<rz_max ; rz++) { if (rz) quat_concat_euler(q, YAW, dz); /* build total rotation matrix */ quat_matrix(mat, q); /* transform the cores and shells */ i = 0; for (list=model->selection ; list ; list=g_slist_next(list)) { core = list->data; /* FIXME - should we restore this after? how? */ core->region = 2; /* get original selection core coordinates */ core2 = g_slist_nth_data(core_list, i); ARR3SET(core->x, core2->x); /* perform the rotation (NB: must be done about origin in cartesian space) */ ARR3SUB(core->x, dock_centroid); vecmat(model->latmat, core->x); vecmat(mat, core->x); vecmat(model->ilatmat, core->x); ARR3ADD(core->x, dock_centroid); /* add the current translation offset */ ARR3ADD(core->x, x); /* as above, for the associated shell */ if (core->shell) { shell = core->shell; shell->region = 2; shell2 = core2->shell; g_assert(shell2 != NULL); ARR3SET(shell->x, shell2->x); ARR3SUB(shell->x, dock_centroid); vecmat(model->latmat, shell->x); vecmat(mat, shell->x); vecmat(model->ilatmat, shell->x); ARR3ADD(shell->x, dock_centroid); ARR3ADD(shell->x, x); } i++; } /* write docking configuration */ /* file = g_strdup_printf("%s_%06d.gin", model->basename, n); */ /* m identifies grid points (for later minimum check) */ fprintf(fp, "%s_%06d.gin %f %f %d\n", model->basename, n, x[0], x[1], m); file = g_strdup_printf("%s%s%s_%06d.gin", dock->path, DIR_SEP, model->basename, n); dump = g_strdup_printf("%s_%06d.res", model->basename, n); model->gulp.dump_file = dump; write_gulp(file, model); g_free(file); g_free(dump); n++; } } } m++; } } /* restore original variables */ model->gulp.dump_file = dump_save; model->gulp.rigid = rigid_save; g_free(model->gulp.rigid_move); model->gulp.rigid_move = rigid_move_save; /* restore original selection (delete, then concat saved list) */ i = 0; for (list=model->selection ; list ; list=g_slist_next(list)) { core = list->data; core2 = g_slist_nth_data(core_list, i); ARR3SET(core->x, core2->x); if (core->shell) { shell = core->shell; shell2 = core2->shell; g_assert(shell2 != NULL); ARR3SET(shell->x, shell2->x); } i++; } /* free docking core/shell lists */ free_slist(core_list); free_slist(shell_list); g_string_free(name, TRUE); fclose(fp); /* run docking in background unless told to stop after setup */ /* if (!dock_no_execute) submit_task("Docking", &docking_execute, dock, &docking_cleanup, dock, model); */ }
GSList *get_facet_equiv(struct model_pak *data, gint *f1) { gint i, flag, *f2, index[3]; gdouble d1, d2, vec[3]; GSList *flist=NULL, *list=NULL; g_return_val_if_fail(data != NULL, NULL); g_return_val_if_fail(f1 != NULL, NULL); /* NEW */ ARR3SET(vec, f1); vecmat(data->rlatmat, vec); d1 = 1.0/VEC3MAG(vec); #if DEBUG_GET_FACET_EQUIV printf("search for equiv faces to (%d %d %d) (Dhkl = %f)\n", f1[0], f1[1], f1[2], d1); #endif /* add the supplied face to the list (needed to eliminate repetitions) */ f2 = g_malloc(3*sizeof(gint)); ARR3SET(f2, f1); flist = g_slist_prepend(flist, (gpointer) f2); if (data->sginfo.spacenum) { /* skip 1st (trivial) op */ for (i=1 ; i<data->sginfo.order ; i++) { /* generate new symmetry related hkl */ ARR3SET(vec, f1); vecmat(*(data->sginfo.matrix+i), vec); ARR3SET(index, vec); /* NEW - weed out symop generated faces with different Dhkl values */ /* FIXME - why does this happen??? */ vecmat(data->rlatmat, vec); d2 = 1.0/VEC3MAG(vec); #if DEBUG_GET_FACET_EQUIV printf("candidate: (%3d %3d %3d) : (Dhkl=%7.4f)", index[0], index[1], index[2], d2); #endif if (fabs(d2-d1) > FRACTION_TOLERANCE) { #if DEBUG_GET_FACET_EQUIV printf("[NO : dhkl mis-match]\n"); #endif continue; } /* add new hkl if not found in the list */ flag = 0; list = flist; while (list != NULL) { f2 = (gint *) list->data; if (index[0] == f2[0] && index[1] == f2[1] && index[2] == f2[2]) { flag++; break; } list = g_slist_next(list); } if (!flag) { f2 = g_malloc(3*sizeof(gint)); ARR3SET(f2, index); flist = g_slist_prepend(flist, f2); #if DEBUG_GET_FACET_EQUIV printf("[YES : symop %d]\n", i); #endif } #if DEBUG_GET_FACET_EQUIV else { printf("[NO : already exists]\n"); } #endif } } else printf("No space group information.\n"); flist = g_slist_reverse(flist); return(flist); }
gint siesta_phonon_timer(gpointer dialog) { static gint count=0; gint atom, mode; gchar *text, *name; gdouble f, x1[3]; gpointer spin; GSList *list; struct core_pak *core; struct model_pak *model; /* checks */ if (!dialog_valid(dialog)) return(FALSE); model = dialog_model(dialog); g_assert(model != NULL); /* stop animation? */ if (!model->pulse_direction) { siesta_phonon_cleanup(model); coords_compute(model); redraw_canvas(SINGLE); return(FALSE); } /* setup animation resolution */ spin = dialog_child_get(dialog, "phonon_resolution"); model->pulse_max = SPIN_FVAL(spin); /* setup scaling for this step */ model->pulse_count += model->pulse_direction; if (model->pulse_count <= -model->pulse_max) { model->pulse_count = -model->pulse_max; model->pulse_direction = 1; } if (model->pulse_count >= model->pulse_max) { model->pulse_count = model->pulse_max; model->pulse_direction = -1; } spin = dialog_child_get(dialog, "phonon_scaling"); f = SPIN_FVAL(spin); f *= (gdouble) model->pulse_count; f /= model->pulse_max; atom = 0; mode = model->siesta.sorted_eig_values[model->siesta.current_animation]; /* get eigenvectors from all atoms */ for (list=model->cores ; list; list=g_slist_next(list)) { core = list->data; ARR3SET(x1, core->x); //get x,y,z for given freq. core->offset[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, mode); core->offset[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, mode); core->offset[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, mode); atom++; /* pulse offset scaling */ VEC3MUL(core->offset, f); vecmat(model->ilatmat, core->offset); } /* recalc coords */ coords_compute(model); /* CURRENT - output to povray for movie rendering */ if (model->phonon_movie) { if (!model->pulse_count && model->pulse_direction==1) { model->phonon_movie = FALSE; count=0; text = g_strdup_printf("%s -delay 20 %s_*.tga %s.%s", sysenv.convert_path, model->phonon_movie_name, model->phonon_movie_name, model->phonon_movie_type); system(text); g_free(text); return(FALSE); } else { text = g_strdup_printf("%s_%06d.pov", model->phonon_movie_name, count++); name = g_build_filename(sysenv.cwd, text, NULL); write_povray(name, model); povray_exec(sysenv.cwd, name); g_free(text); g_free(name); } } else redraw_canvas(SINGLE); return(TRUE); }