OSDN Git Service

Frames can now have variable unit cell parameters.
authortoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Wed, 31 Mar 2010 12:46:38 +0000 (12:46 +0000)
committertoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Wed, 31 Mar 2010 12:46:38 +0000 (12:46 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@27 a2be9bc6-48de-4e38-9406-05402d4bc13c

MolLib/MD/MDCore.c
MolLib/MD/MDCore.h
MolLib/MolAction.c
MolLib/Molecule.c
MolLib/Molecule.h
MolLib/Ruby_bind/ruby_bind.c
MolLib/Ruby_bind/ruby_md.c
memo.txt
wxSources/MyDocument.cpp

index fa05fe4..dd2ebe9 100644 (file)
@@ -1589,16 +1589,24 @@ md_prepare(MDArena *arena, int check_only)
        }
 
        /*  Allocate ring buffer   */
-       if (arena->ring != NULL)
+       if (arena->ring != NULL) {
+               free(arena->ring->buf);
                free(arena->ring);
-       arena->nringframes = 2000 / mol->natoms;
-       if (arena->nringframes == 0)
-               arena->nringframes = 1;
-       arena->ring = (Vector *)malloc(sizeof(Vector) * mol->natoms * arena->nringframes);
+       }
+       arena->ring = (MDRing *)calloc(sizeof(MDRing), 1);
        if (arena->ring == NULL)
                md_panic(arena, ERROR_out_of_memory);
-       arena->ring_next = 0;
-       arena->ring_count = 0;
+       arena->ring->size = mol->natoms;
+       if (arena->pressure != NULL && arena->pressure->disabled == 0)
+               arena->ring->size += 4;
+       arena->ring->nframes = 2000 / arena->ring->size;
+       if (arena->ring->nframes < 2)
+               arena->ring->nframes = 2;
+       arena->ring->buf = (Vector *)calloc(sizeof(Vector), arena->ring->size * arena->ring->nframes);
+       if (arena->ring->buf == NULL)
+               md_panic(arena, ERROR_out_of_memory);
+       arena->ring->next = 0;
+       arena->ring->count = 0;
 
        /*  Initialize temperature statistics  */
        arena->sum_temperature = 0.0;
index c86cad9..858ab73 100644 (file)
@@ -129,6 +129,15 @@ typedef struct MDGroupFlags {
 #define get_group_flag(gf, n) (n < (gf)->natoms ? (gf)->flags[(n)/8] & group_flag_mask[(n)%8] : 0)
 #define set_group_flag(gf, n, bool) (n < (gf)->natoms ? (bool ? ((gf)->flags[(n)/8] |= group_flag_mask[(n)%8]) : ((gf)->flags[(n)/8] &= ~(group_flag_mask[(n)%8]))) : 0)
 
+/*  Ring buffer for sending coordinates to another thread  */
+typedef struct MDRing {
+       Vector *buf;           /*  Vector buffer  */
+       Int    size;           /*  Number of vectors per frame; natoms + (use_cell ? 4 : 0)  */
+       Int    nframes;        /*  Number of frames in the ring buffer (2000 / natoms)  */
+       Int    next;           /*  Next frame index to store data  */
+       Int    count;          /*  Number of frames currently in the ring buffer  */
+} MDRing;
+       
 /*  Everything needed for MD  */
 typedef struct MDArena {
        Int refCount;
@@ -267,10 +276,7 @@ typedef struct MDArena {
 
        Int    natoms_uniq;     /*  Number of symmetry-unique atoms  */
        
-       Vector *ring;           /*  Ring buffer for sending coordinates between threads */
-       Int    nringframes;     /*  Number of frames in the ring buffer (2000 / natoms)  */
-       Int    ring_next;       /*  Next frame index to store data  */
-       Int    ring_count;      /*  Number of frames currently in the ring buffer  */
+       MDRing *ring;
 
        /*  Parameters are copied from mol->par and gBuiltinParameters for each call to md_prepare()  */
        Parameter *par;
index df6c416..6ddc272 100644 (file)
@@ -42,7 +42,7 @@ const char *gMolActionTranslateAtoms  = "translateAtoms:vG";
 const char *gMolActionRotateAtoms     = "rotate:vdvG";
 const char *gMolActionTransformAtoms  = "transform:tG";
 const char *gMolActionSetAtomPositions = "atomPosition:GV";
-const char *gMolActionInsertFrames    = "insertFrames:GV";
+const char *gMolActionInsertFrames    = "insertFrames:GVV";
 const char *gMolActionRemoveFrames    = "removeFrames:G";
 const char *gMolActionSetSelection    = "selection:G";
 const char *gMolActionChangeResidueNumber = "changeResSeq:Gi";
@@ -973,15 +973,19 @@ MolActionPerform(Molecule *mol, MolAction *action)
                needsSymmetryAmendment = 1;
        } else if (strcmp(action->name, gMolActionInsertFrames) == 0) {
                int old_nframes, new_nframes;
+               Vector *vp2;
                ig = action->args[0].u.igval;
                vp = (Vector *)action->args[1].u.arval.ptr;
+               vp2 = (Vector *)action->args[2].u.arval.ptr;
                n1 = IntGroupGetCount(ig);
                if (n1 == 0)
                        return 0;  /*  Do nothing  */
                if (vp != NULL && action->args[1].u.arval.nitems != n1 * mol->natoms)
                        return -1;  /*  Internal inconsistency  */
+               if (vp2 != NULL && action->args[2].u.arval.nitems != n1 * 4)
+                       return -1;  /*  Internal inconsistency  */
                old_nframes = MoleculeGetNumberOfFrames(mol);
-               if (MoleculeInsertFrames(mol, ig, vp) < 0)
+               if (MoleculeInsertFrames(mol, ig, vp, vp2) < 0)
                        return -1;  /*  Error  */
                new_nframes = MoleculeGetNumberOfFrames(mol);
                if (old_nframes + n1 < new_nframes) {
@@ -996,16 +1000,22 @@ MolActionPerform(Molecule *mol, MolAction *action)
                act2 = MolActionNew(gMolActionRemoveFrames, ig);
                act2->frame = mol->cframe;
        } else if (strcmp(action->name, gMolActionRemoveFrames) == 0) {
+               Vector *vp2;
                ig = action->args[0].u.igval;
                n1 = IntGroupGetCount(ig);
                if (n1 == 0)
                        return 0;  /*  Do nothing  */
                vp = (Vector *)calloc(sizeof(Vector), n1 * mol->natoms);
-               if (MoleculeRemoveFrames(mol, ig, vp) < 0)
+               if (mol->cell != NULL && mol->frame_cells != NULL)
+                       vp2 = (Vector *)calloc(sizeof(Vector) * 4, n1);
+               else vp2 = NULL;
+               if (MoleculeRemoveFrames(mol, ig, vp, vp2) < 0)
                        return -1;  /*  Error  */
-               act2 = MolActionNew(gMolActionInsertFrames, ig, n1 * mol->natoms, vp);
+               act2 = MolActionNew(gMolActionInsertFrames, ig, n1 * mol->natoms, vp, (vp2 != NULL ? n1 * 4 : 0), vp2);
                act2->frame = mol->cframe;
                free(vp);
+               if (vp2 != NULL)
+                       free(vp2);
        } else if (strcmp(action->name, gMolActionSetSelection) == 0) {
                IntGroup *ig2;
                ig2 = MoleculeGetSelection(mol);
index 6a95bfd..d5a0723 100755 (executable)
@@ -2249,7 +2249,7 @@ MoleculeLoadGamessDatFile(Molecule *mol, const char *fname, char *errbuf, int er
                                vbuf[i].z = dval[3];
                        }
                        ig = IntGroupNewWithPoints(nframes, 1, -1);
-                       MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, natoms, vbuf);
+                       MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, natoms, vbuf, 0, NULL);
                        IntGroupRelease(ig);
                        nframes++;
                        if (n1) {
@@ -2589,7 +2589,8 @@ MoleculeReadCoordinatesFromDcdFile(Molecule *mp, const char *fname, char *errbuf
                        vpp->z = zp[i];
                }
        }
-       if (MoleculeInsertFrames(mp, ig, vp) < 0)
+       /*  TODO: implement frame-specific cells  */
+       if (MoleculeInsertFrames(mp, ig, vp, NULL) < 0)
                snprintf(errbuf, errbufsize, "Cannot insert frames");
        if (dcd.with_unitcell) {
                Vector ax, ay, az, orig;
@@ -7329,21 +7330,21 @@ MoleculeCalculateCellFromAxes(XtalCell *cp, int calc_abc)
                return -1;  /*  Non-regular transform  */
 
        /*  Calculate the reciprocal cell parameters  */
-       cp->rcell[0] = sqrt(cp->rtr[0] * cp->rtr[0] + cp->rtr[1] * cp->rtr[1] + cp->rtr[2] * cp->rtr[2]);
-       cp->rcell[1] = sqrt(cp->rtr[3] * cp->rtr[3] + cp->rtr[4] * cp->rtr[4] + cp->rtr[5] * cp->rtr[5]);
-       cp->rcell[2] = sqrt(cp->rtr[6] * cp->rtr[6] + cp->rtr[7] * cp->rtr[7] + cp->rtr[8] * cp->rtr[8]);
-       cp->rcell[3] = acos((cp->rtr[3] * cp->rtr[6] + cp->rtr[4] * cp->rtr[7] + cp->rtr[5] * cp->rtr[8]) / (cp->rcell[1] * cp->rcell[2])) * kRad2Deg;
-       cp->rcell[4] = acos((cp->rtr[6] * cp->rtr[0] + cp->rtr[7] * cp->rtr[1] + cp->rtr[8] * cp->rtr[2]) / (cp->rcell[2] * cp->rcell[0])) * kRad2Deg;
-       cp->rcell[5] = acos((cp->rtr[0] * cp->rtr[3] + cp->rtr[1] * cp->rtr[4] + cp->rtr[2] * cp->rtr[5]) / (cp->rcell[0] * cp->rcell[1])) * kRad2Deg;
+       cp->rcell[0] = sqrt(cp->rtr[0] * cp->rtr[0] + cp->rtr[3] * cp->rtr[3] + cp->rtr[6] * cp->rtr[6]);
+       cp->rcell[1] = sqrt(cp->rtr[1] * cp->rtr[1] + cp->rtr[4] * cp->rtr[4] + cp->rtr[7] * cp->rtr[7]);
+       cp->rcell[2] = sqrt(cp->rtr[2] * cp->rtr[2] + cp->rtr[5] * cp->rtr[5] + cp->rtr[8] * cp->rtr[8]);
+       cp->rcell[3] = acos((cp->rtr[1] * cp->rtr[2] + cp->rtr[4] * cp->rtr[5] + cp->rtr[7] * cp->rtr[8]) / (cp->rcell[1] * cp->rcell[2])) * kRad2Deg;
+       cp->rcell[4] = acos((cp->rtr[2] * cp->rtr[0] + cp->rtr[5] * cp->rtr[3] + cp->rtr[8] * cp->rtr[6]) / (cp->rcell[2] * cp->rcell[0])) * kRad2Deg;
+       cp->rcell[5] = acos((cp->rtr[0] * cp->rtr[1] + cp->rtr[3] * cp->rtr[4] + cp->rtr[6] * cp->rtr[7]) / (cp->rcell[0] * cp->rcell[1])) * kRad2Deg;
        
-       if (!calc_abc) {
+       if (calc_abc) {
                /*  Calculate a, b, c, alpha, beta, gamma  */
-               cp->cell[0] = sqrt(cp->tr[0] * cp->tr[0] + cp->tr[1] * cp->tr[1] + cp->tr[2] * cp->tr[2]);
-               cp->cell[1] = sqrt(cp->tr[3] * cp->tr[3] + cp->tr[4] * cp->tr[4] + cp->tr[5] * cp->tr[5]);
-               cp->cell[2] = sqrt(cp->tr[6] * cp->tr[6] + cp->tr[7] * cp->tr[7] + cp->tr[8] * cp->tr[8]);
-               cp->cell[3] = acos((cp->tr[3] * cp->tr[6] + cp->tr[4] * cp->tr[7] + cp->tr[5] * cp->tr[8]) / (cp->cell[1] * cp->cell[2])) * kRad2Deg;
-               cp->cell[4] = acos((cp->tr[6] * cp->tr[0] + cp->tr[7] * cp->tr[1] + cp->tr[8] * cp->tr[2]) / (cp->cell[2] * cp->cell[0])) * kRad2Deg;
-               cp->cell[5] = acos((cp->tr[0] * cp->tr[3] + cp->tr[1] * cp->tr[4] + cp->tr[2] * cp->tr[5]) / (cp->cell[0] * cp->cell[1])) * kRad2Deg;
+               cp->cell[0] = sqrt(cp->tr[0] * cp->tr[0] + cp->tr[3] * cp->tr[3] + cp->tr[6] * cp->tr[6]);
+               cp->cell[1] = sqrt(cp->tr[1] * cp->tr[1] + cp->tr[4] * cp->tr[4] + cp->tr[7] * cp->tr[7]);
+               cp->cell[2] = sqrt(cp->tr[2] * cp->tr[2] + cp->tr[5] * cp->tr[5] + cp->tr[8] * cp->tr[8]);
+               cp->cell[3] = acos((cp->tr[1] * cp->tr[2] + cp->tr[4] * cp->tr[5] + cp->tr[7] * cp->tr[8]) / (cp->cell[1] * cp->cell[2])) * kRad2Deg;
+               cp->cell[4] = acos((cp->tr[2] * cp->tr[0] + cp->tr[5] * cp->tr[3] + cp->tr[8] * cp->tr[6]) / (cp->cell[2] * cp->cell[0])) * kRad2Deg;
+               cp->cell[5] = acos((cp->tr[0] * cp->tr[1] + cp->tr[3] * cp->tr[4] + cp->tr[6] * cp->tr[7]) / (cp->cell[0] * cp->cell[1])) * kRad2Deg;
        }
        
        return 0;
@@ -7736,9 +7737,9 @@ MoleculeGetNumberOfFrames(Molecule *mp)
 }
 
 int
-MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame)
+MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame, const Vector *inFrameCell)
 {
-       int i, j, count, n_new, n_old, natoms, exframes, last_inserted;
+       int i, j, count, n_new, n_old, natoms, exframes, last_inserted, old_count;
        Vector *tempv, *vp;
        Atom *ap;
        if (mp == NULL || (natoms = mp->natoms) == 0 || (count = IntGroupGetCount(group)) <= 0)
@@ -7752,7 +7753,7 @@ MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame)
                n_new += exframes;
        } else exframes = 0;
 
-       tempv = (Vector *)malloc(sizeof(Vector) * n_new);
+       tempv = (Vector *)malloc(sizeof(Vector) * n_new * 4);  /*  "*4" for handling cells  */
        if (tempv == NULL)
                return -1;
 
@@ -7771,6 +7772,17 @@ MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame)
                        vp[j] = ap->r;
                ap->frames = vp;
        }
+       if (mp->cell != NULL && (mp->frame_cells != NULL || inFrameCell != NULL)) {
+               if (mp->frame_cells == NULL)
+                       vp = (Vector *)calloc(sizeof(Vector), n_new * 4);
+               else
+                       vp = (Vector *)realloc(mp->frame_cells, sizeof(Vector) * 4 * n_new);
+               if (vp == NULL) {
+                       __MoleculeUnlock(mp);
+                       return -1;
+               }
+               mp->frame_cells = vp;
+       }
        
        /*  group = [n0..n1-1, n2..n3-1, ...]  */
        /*  s = t = 0,  */
@@ -7781,31 +7793,56 @@ MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame)
                ...
                tempv[nl..n_new-1] <- ap[s..s+(n_new-nl-1)], s += n_new-nl
                At last, s will become n_old and t will become count.  */
-       for (i = 0, ap = mp->atoms; i < mp->natoms; i++, ap = ATOM_NEXT(ap)) {
-               int s, t, ns, ne;
-               Vector cr = ap->r;
+       for (i = 0, ap = mp->atoms; i <= mp->natoms; i++, ap = ATOM_NEXT(ap)) {
+               int s, t, ns, ne, mult;
+               Vector cr;
                ne = s = t = 0;
-               vp = ap->frames;
+               if (i == mp->natoms) {
+                       if (mp->cell == NULL || mp->frame_cells == NULL)
+                               break;
+                       vp = mp->frame_cells;
+                       mult = 4;
+               } else {
+                       cr = ap->r;
+                       vp = ap->frames;
+                       mult = 1;
+               }
                for (j = 0; (ns = IntGroupGetStartPoint(group, j)) >= 0; j++) {
                        if (ns > ne) {
-                               memmove(tempv + ne, vp + s, sizeof(Vector) * (ns - ne));
+                               memmove(tempv + ne * mult, vp + s * mult, sizeof(Vector) * mult * (ns - ne));
                                s += ns - ne;
                        }
                        ne = IntGroupGetEndPoint(group, j);
                        while (ns < ne) {
-                               if (inFrame != NULL)
-                                       tempv[ns] = inFrame[natoms * t + i];
-                               else tempv[ns] = cr;
+                               if (i == mp->natoms) {
+                                       if (inFrameCell != NULL) {
+                                               tempv[ns * 4] = inFrameCell[t * 4];
+                                               tempv[ns * 4 + 1] = inFrameCell[t * 4 + 1];
+                                               tempv[ns * 4 + 2] = inFrameCell[t * 4 + 2];
+                                               tempv[ns * 4 + 3] = inFrameCell[t * 4 + 3];
+                                       } else {
+                                               tempv[ns * 4] = mp->cell->axes[0];
+                                               tempv[ns * 4 + 1] = mp->cell->axes[1];
+                                               tempv[ns * 4 + 2] = mp->cell->axes[2];
+                                               tempv[ns * 4 + 3] = mp->cell->origin;
+                                       }
+                               } else {
+                                       if (inFrame != NULL)
+                                               tempv[ns] = inFrame[natoms * t + i];
+                                       else
+                                               tempv[ns] = cr;
+                               }
                                t++;
                                ns++;
                        }
                }
                if (n_new > ne) {
-                       memmove(tempv + ne, vp + s, sizeof(Vector) * (n_new - ne));
+                       memmove(tempv + ne * mult, vp + s * mult, sizeof(Vector) * mult * (n_new - ne));
                        s += n_new - ne;
                }
-               ap->nframes = n_new;
-               memmove(vp, tempv, sizeof(Vector) * n_new);
+               if (i < mp->natoms)
+                       ap->nframes = n_new;
+               memmove(vp, tempv, sizeof(Vector) * mult * n_new);
        }
        free(tempv);
        mp->nframes = n_new;
@@ -7816,9 +7853,9 @@ MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame)
 }
 
 int
-MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame)
+MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame, Vector *outFrameCell)
 {
-       int i, count, n_new, n_old, natoms, nframes;
+       int i, count, n_new, n_old, natoms, nframes, old_count;
        Vector *tempv, *vp;
        Atom *ap;
        if (mp == NULL || (natoms = mp->natoms) == 0 || (count = IntGroupGetCount(group)) <= 0)
@@ -7826,12 +7863,14 @@ MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame)
 
        /*  outFrame[] should have enough size for Vector * natoms * group.count  */
        memset(outFrame, 0, sizeof(Vector) * natoms * count);
+       if (mp->cell != NULL && mp->frame_cells != NULL)
+               memset(outFrameCell, 0, sizeof(Vector) * 4 * count);
 
        n_old = MoleculeGetNumberOfFrames(mp);
        n_new = n_old - count;
        if (n_new < 0)
                n_new = 0;
-       tempv = (Vector *)malloc(sizeof(Vector) * n_old);
+       tempv = (Vector *)malloc(sizeof(Vector) * n_old * 4);  /*  "*4" for handling cells  */
        if (tempv == NULL)
                return -1;
 
@@ -7846,49 +7885,77 @@ MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame)
                At last, s will become n_new and t will become count.  */
        __MoleculeLock(mp);
        nframes = 0;
-       for (i = 0, ap = mp->atoms; i < mp->natoms; i++, ap = ATOM_NEXT(ap)) {
+       for (i = 0, ap = mp->atoms; i <= mp->natoms; i++, ap = ATOM_NEXT(ap)) {
                int s, t, j, ns, ne;
-               /*  Copy ap->frames to tempv  */
-               memset(tempv, 0, sizeof(Vector) * n_old);
-               vp = ap->frames;
-               if (vp != NULL)
-                       memmove(tempv, vp, sizeof(Vector) * (ap->nframes > n_old ? n_old : ap->nframes));
-               else {
-                       ap->frames = vp = (Vector *)calloc(sizeof(Vector), n_old);
+               int mult;
+               /*  if i == mp->natoms, mp->frame_cells is handled  */
+               if (i == mp->natoms) {
+                       if (mp->cell == NULL || mp->frame_cells == NULL)
+                               break;
+                       mult = 4;
+                       vp = mp->frame_cells;
+                       old_count = n_old;
+               } else {
+                       mult = 1;
+                       vp = ap->frames;
                        if (vp == NULL) {
-                               __MoleculeUnlock(mp);
-                               return -1;
+                               ap->frames = vp = (Vector *)calloc(sizeof(Vector), n_old);
+                               if (vp == NULL) {
+                                       __MoleculeUnlock(mp);
+                                       return -1;
+                               }
                        }
+                       old_count = ap->nframes;
                }
+
+               /*  Copy vp to tempv  */
+               memset(tempv, 0, sizeof(Vector) * mult * n_old);
+               memmove(tempv, vp, sizeof(Vector) * mult * (old_count > n_old ? n_old : old_count));
                ne = ns = s = t = 0;
                for (j = 0; ns < n_old && (ns = IntGroupGetStartPoint(group, j)) >= 0; j++) {
                        if (ns > n_old)
                                ns = n_old;
                        if (ns > ne) {
-                               memmove(vp + s, tempv + ne, sizeof(Vector) * (ns - ne));
+                               memmove(vp + s * mult, tempv + ne * mult, sizeof(Vector) * mult * (ns - ne));
                                s += ns - ne;
                        }
                        ne = IntGroupGetEndPoint(group, j);
                        if (ne > n_old)
                                ne = n_old;
                        while (ns < ne) {
-                               outFrame[natoms * t + i] = tempv[ns];
+                               if (i < mp->natoms)
+                                       outFrame[natoms * t + i] = tempv[ns];
+                               else if (outFrameCell != NULL) {
+                                       outFrameCell[i * 4] = tempv[ns * 4];
+                                       outFrameCell[i * 4 + 1] = tempv[ns * 4 + 1];
+                                       outFrameCell[i * 4 + 2] = tempv[ns * 4 + 2];
+                                       outFrameCell[i * 4 + 3] = tempv[ns * 4 + 3];
+                               }
                                t++;
                                ns++;
                        }
                }
                if (n_old > ne) {
-                       memmove(vp + s, tempv + ne, sizeof(Vector) * (n_old - ne));
+                       memmove(vp + s * mult, tempv + ne * mult, sizeof(Vector) * mult * (n_old - ne));
                        s += n_old - ne;
                }
-               ap->nframes = s;
+               if (i < mp->natoms)
+                       ap->nframes = s;
                if (nframes < s)
                        nframes = s;
                if (s == 0) {
-                       free(ap->frames);
-                       ap->frames = NULL;
+                       if (i < mp->natoms) {
+                               free(ap->frames);
+                               ap->frames = NULL;
+                       } else {
+                               free(mp->frame_cells);
+                               mp->frame_cells = NULL;
+                       }
                } else {
-                       ap->frames = (Vector *)realloc(ap->frames, sizeof(Vector) * s);
+                       if (i < mp->natoms)
+                               ap->frames = (Vector *)realloc(ap->frames, sizeof(Vector) * s);
+                       else
+                               mp->frame_cells = (Vector *)realloc(mp->frame_cells, sizeof(Vector) * 4 * s);
                }
        }
        free(tempv);
@@ -7903,6 +7970,7 @@ MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame)
        return count;
 }
 
+#if 0
 int
 MoleculeInsertFrame(Molecule *mp, int index, const Vector *inFrame)
 {
@@ -7985,6 +8053,7 @@ MoleculeRemoveFrame(Molecule *mp, int frame, Vector *outFrame)
        __MoleculeUnlock(mp);
        return frame;
 }
+#endif
 
 int
 MoleculeSelectFrame(Molecule *mp, int frame, int copyback)
@@ -8008,6 +8077,11 @@ MoleculeSelectFrame(Molecule *mp, int frame, int copyback)
                        ok = 1;
                }
        }
+
+       if (mp->cell != NULL && mp->frame_cells != NULL) {
+               MoleculeSetPeriodicBox(mp, &mp->frame_cells[frame * 4], &mp->frame_cells[frame * 4 + 1], &mp->frame_cells[frame * 4 + 2], &mp->frame_cells[frame * 4 + 3], mp->cell->flags);
+       }
+
        __MoleculeUnlock(mp);
        if (ok) {
                mp->cframe = frame;
index 681dbb1..14fb772 100755 (executable)
@@ -253,6 +253,9 @@ typedef struct Molecule {
        Int    nframes;      /*  The number of frames. This is a cached value, and should be
                                                         recalculated from the atoms if it is -1  */
        Int    cframe;       /*  The current frame number  */
+
+       Vector *frame_cells; /*  The cell vectors for frames; (nframes*3) array of Vectors  */
+
        struct MainView *mview;  /*  Reference to the MainView object if present (no retain)  */
        Int    modifyCount;  /*  Internal counter for modification. This value is not to be modified
                                 manually; instead, call MoleculeIncrementModifyCount() whenever
@@ -448,10 +451,10 @@ int MoleculeIsFragmentDetachable(Molecule *mp, IntGroup *group, int *n1, int *n2
 int MoleculeIsFragmentRotatable(Molecule *mp, IntGroup *group, int *n1, int *n2, IntGroup **rotGroup);
 
 int MoleculeGetNumberOfFrames(Molecule *mp);
-int MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame);
-int MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame);
-int MoleculeInsertFrame(Molecule *mp, int index, const Vector *inFrame);
-int MoleculeRemoveFrame(Molecule *mp, int frame, Vector *outFrame);
+int MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame, const Vector *inFrameCell);
+int MoleculeRemoveFrames(Molecule *mp, IntGroup *group, Vector *outFrame, Vector *outFrameCell);
+/*int MoleculeInsertFrame(Molecule *mp, int index, const Vector *inFrame);
+int MoleculeRemoveFrame(Molecule *mp, int frame, Vector *outFrame); */
 int MoleculeSelectFrame(Molecule *mp, int frame, int copyback);
 
 int MoleculeCalcMO(Molecule *mp, Int mono, const Vector *op, const Vector *dxp, const Vector *dyp, const Vector *dzp, Int nx, Int ny, Int nz, int (*callback)(double progress, void *ref), void *ref);
index 199cba1..d8c1fa1 100644 (file)
@@ -5920,8 +5920,8 @@ s_Molecule_Nframes(VALUE self)
 
 /*
  *  call-seq:
- *     insert_frame(integer, coordinates = nil) -> bool
- *     insert_frames(intGroup = nil, coordinates = nil) -> bool
+ *     insert_frame(integer, coordinates = nil, cell_axes = nil) -> bool
+ *     insert_frames(intGroup = nil, coordinates = nil, cell_axes = nil) -> bool
  *
  *  Insert new frames at the indices specified by the intGroup. If the first argument is
  *  an integer, a single new frame is inserted at that index. If the first argument is 
@@ -5934,18 +5934,26 @@ s_Molecule_Nframes(VALUE self)
 static VALUE
 s_Molecule_InsertFrames(int argc, VALUE *argv, VALUE self)
 {
-       VALUE val, coords;
+       VALUE val, coords, cells;
     Molecule *mol;
        IntGroup *ig;
        int count, ival, i, j, len, nframes;
-       Vector *vp;
+       Vector *vp, *vp2;
     Data_Get_Struct(self, Molecule, mol);
-       rb_scan_args(argc, argv, "11", &val, &coords);
+       rb_scan_args(argc, argv, "12", &val, &coords, &cells);
        if (coords != Qnil) {
                if (TYPE(coords) != T_ARRAY)
                        rb_raise(rb_eTypeError, "the coordinates should be given as an array of Vector3D");
                len = RARRAY_LEN(coords);
        } else len = 0;
+       if (cells != Qnil) {
+               if (mol->cell == NULL)
+                       rb_raise(rb_eTypeError, "the unit cell is not defined but the cell axes are given");
+               if (TYPE(cells) != T_ARRAY)
+                       rb_raise(rb_eTypeError, "the cell axes should be given as an array of Vector3D");
+               if (len != RARRAY_LEN(coords))
+                       rb_raise(rb_eTypeError, "the number of entries for coordinates and cell axes does not match");
+       }
        nframes = MoleculeGetNumberOfFrames(mol);
        if (val == Qnil) {
                ig = IntGroupNewWithPoints(nframes, (len > 0 ? len : 1), -1);
@@ -5955,14 +5963,16 @@ s_Molecule_InsertFrames(int argc, VALUE *argv, VALUE self)
        }
        count = IntGroupGetCount(ig);
        vp = ALLOC_N(Vector, mol->natoms * count);
+       if (cells != Qnil && len > 0)
+               vp2 = ALLOC_N(Vector, 4 * count);
+       else vp2 = NULL;
        if (len > 0) {
-               VALUE *ptr;
+               VALUE *ptr, *ptr2;
+               int j, len2;
                if (len < count)
                        rb_raise(rb_eMolbyError, "the coordinates should contain no less than %d arrays (for frames)", count);
                ptr = RARRAY_PTR(coords);
                for (i = 0; i < len; i++) {
-                       VALUE *ptr2;
-                       int j, len2;
                        if (TYPE(ptr[i]) != T_ARRAY)
                                rb_raise(rb_eTypeError, "the coordinate array contains non-array object at index %d", i);
                        len2 = RARRAY_LEN(ptr[i]);
@@ -5972,6 +5982,19 @@ s_Molecule_InsertFrames(int argc, VALUE *argv, VALUE self)
                        for (j = 0; j < mol->natoms; j++)
                                VectorFromValue(ptr2[j], &vp[i * mol->natoms + j]);
                }
+               if (vp2 != NULL) {
+                       ptr = RARRAY_PTR(cells);
+                       for (i = 0; i < len; i++) {
+                               if (TYPE(ptr[i]) != T_ARRAY)
+                                       rb_raise(rb_eTypeError, "the cell parameter array contains non-array object at index %d", i);
+                               len2 = RARRAY_LEN(ptr[i]);
+                               if (len2 < 4)
+                                       rb_raise(rb_eMolbyError, "the cell parameter should contain 4 vectors");
+                               ptr2 = RARRAY_PTR(ptr[i]);
+                               for (j = 0; j < 4; j++)
+                                       VectorFromValue(ptr2[j], &vp2[i * 4 + j]);
+                       }
+               }
        } else {
                Atom *ap;
                for (i = 0; i < count; i++) {
@@ -5980,9 +6003,11 @@ s_Molecule_InsertFrames(int argc, VALUE *argv, VALUE self)
                        }
                }
        }
-       ival = MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, mol->natoms * count, vp);
+       ival = MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, mol->natoms * count, vp, (vp2 != NULL ? 4 * count : 0), vp2);
        IntGroupRelease(ig);
        free(vp);
+       if (vp2 != NULL)
+               free(vp2);
        return (ival >= 0 ? val : Qnil);
 }
 
index 9421c72..a6b531e 100644 (file)
@@ -96,7 +96,7 @@ s_MDArena_Run_or_minimize(VALUE self, VALUE arg, int minimize)
        if (arena->step > start_step) {
                /*  Create a new frame and copy new coordinates  */
                ig = IntGroupNewWithPoints(MoleculeGetNumberOfFrames(arena->xmol), 1, -1);
-               MolActionCreateAndPerform(arena->xmol, gMolActionInsertFrames, ig, 0, NULL);
+               MolActionCreateAndPerform(arena->xmol, gMolActionInsertFrames, ig, 0, NULL, 0, NULL);
                IntGroupRelease(ig);
                md_copy_coordinates_from_internal(arena);
        }
index 26e62c6..f8fb3b6 100755 (executable)
--- a/memo.txt
+++ b/memo.txt
@@ -29,4 +29,6 @@ OS 10.4 用のユニバーサルバイナリは、export ISYSROOT='-isysroot /De
   DialogItem は C レベルのデータは持たず、単なる cDialogItem のインスタンスとする。属性は、今まで Dialog 中のハッシュに保持していたが、DialogItem のインスタンス変数として実装する。
   Dialog#item(:type, hash) でアイテムを作成。Dialog#set_attr, Dialog#get_attr はやめて、DialogItem#[], DialogItem#[]= で実装する。DialogItem#属性名, DialogItem#属性名= も実装する(ParameterRef と同様)。また、Dialog#action の引数はアイテム番号でなく DialogItem オブジェクトとする。
   DialogItem の action 属性は今までと同様だが、引数としてはアイテム番号でなく DialogItem オブジェクトそのものが渡される。
-  
\ No newline at end of file
+
+2010.3.21.
+  Pressure control を使えるようにしたい。フレームごとに unit cell パラメータを保持できるようにしないといけない。
index 4528df6..0b7adf9 100755 (executable)
@@ -675,18 +675,27 @@ sDoMolecularDynamics(void *argptr, int argnum)
                                if (mol->requestAbortThread)
                                        r = -1;
                                else {
-
                                        /*  Copy the coordinate to the ring buffer  */
-                                       Vector *rp = mol->arena->ring + mol->natoms * mol->arena->ring_next;
+                                       MDRing *ring = mol->arena->ring;
+                                       Vector *rp = ring->buf + ring->size * ring->next;
                                        Int j;
                                        Atom *ap;
                                        MoleculeLock(mol);
                                        for (j = 0, ap = mol->arena->mol->atoms; j < mol->natoms; j++, ap = ATOM_NEXT(ap)) {
                                                rp[j] = ap->r;
                                        }
-                                       mol->arena->ring_next = (mol->arena->ring_next + 1) % mol->arena->nringframes;
-                                       if (mol->arena->ring_count < mol->arena->nringframes)
-                                               mol->arena->ring_count++;
+                                       if (j < ring->size) {
+                                               XtalCell *cp = mol->arena->mol->cell;
+                                               if (cp != NULL) {
+                                                       rp[j++] = cp->axes[0];
+                                                       rp[j++] = cp->axes[1];
+                                                       rp[j++] = cp->axes[2];
+                                                       rp[j++] = cp->origin;
+                                               }
+                                       }
+                                       ring->next = (ring->next + 1) % ring->nframes;
+                                       if (ring->count < ring->nframes)
+                                               ring->count++;
                                        MoleculeUnlock(mol);
                                        
                                        /*  Create a new frame and copy the new coordinates  */
@@ -758,24 +767,40 @@ MyDocument::OnInsertFrameFromMD(wxCommandEvent &event)
 {
        Int i, j, n, old_nframes;
        Atom *ap;
+       MDRing *ring;
 
        /*  Create new frame(s) and copy the new coordinates from the ring buffer  */
        MoleculeLock(mol);
-       n = mol->arena->ring_count;
+       ring = mol->arena->ring;
+       n = ring->count;
        if (n > 0) {
                IntGroup *ig;
                Vector *rp;
                old_nframes = MoleculeGetNumberOfFrames(mol);
+               /*  It is more convenient to set cell parameter when inserting frames, whereas 
+                   the coordinates can be set afterwards  */
+               if (ring->size > mol->natoms) {
+                       rp = (Vector *)calloc(sizeof(Vector) * 4, n);
+                       for (i = 0; i < n; i++) {
+                               j = ((ring->next - n + i + ring->nframes) % ring->nframes) * ring->size + mol->natoms;
+                               rp[i * 4] = ring->buf[j++];
+                               rp[i * 4 + 1] = ring->buf[j++];
+                               rp[i * 4 + 2] = ring->buf[j++];
+                               rp[i * 4 + 3] = ring->buf[j++];
+                       }
+               } else rp = NULL;
                ig = IntGroupNewWithPoints(old_nframes, n, -1);
-               MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, 0, NULL);
+               MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, 0, NULL, (rp != NULL ? n * 4 : 0), rp);
+               if (rp != NULL)
+                       free(rp);
                IntGroupRelease(ig);
                for (i = 0; i < n; i++) {
                        MoleculeSelectFrame(mol, old_nframes + i, 1);
-                       rp = mol->arena->ring + ((mol->arena->ring_next + mol->arena->nringframes - n + i) % mol->arena->nringframes) * mol->natoms;
+                       rp = ring->buf + ((ring->next - n + i + ring->nframes) % ring->nframes) * ring->size;
                        for (j = 0, ap = mol->atoms; j < mol->natoms; j++, ap = ATOM_NEXT(ap))
                                ap->r = rp[j];
                }
-               mol->arena->ring_count = 0;
+               ring->count = 0;
        }
        MoleculeUnlock(mol);
 }