Molecular Modeling Software
リビジョン | b34d7a601386e61ac0e56444540fdcf6bf838c23 (tree) |
---|---|
日時 | 2012-07-05 00:35:16 |
作者 | toshinagata1964 <toshinagata1964@a2be...> |
コミッター | toshinagata1964 |
Molecule#cell_flexibility and set_cell_flexibility are implemented, and enable/disable_cell_flexibility are removed.
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@257 a2be9bc6-48de-4e38-9406-05402d4bc13c
@@ -58,8 +58,8 @@ const char *gMolActionAddSymmetryOperation = "addSymop:t"; | ||
58 | 58 | const char *gMolActionSetCell = "setCell:Di"; |
59 | 59 | const char *gMolActionSetBox = "setBox:vvvvi"; |
60 | 60 | const char *gMolActionClearBox = "clearBox"; |
61 | -const char *gMolActionEnableCellFlexibility = "enableCellFlexibility:V"; | |
62 | -const char *gMolActionDisableCellFlexibility = "disableCellFlexibility"; | |
61 | +const char *gMolActionSetBoxForFrames = "setBoxForFrames:V"; | |
62 | +const char *gMolActionSetCellFlexibility = "setCellFlexibility:i"; | |
63 | 63 | const char *gMolActionAddParameters = "addParameters:iGU"; |
64 | 64 | const char *gMolActionDeleteParameters = "deleteParameters:iG"; |
65 | 65 | const char *gMolActionCartesianToXtal = "cartesianToXtal"; |
@@ -1366,43 +1366,81 @@ s_MolActionSetBox(Molecule *mol, MolAction *action, MolAction **actp) | ||
1366 | 1366 | return 0; |
1367 | 1367 | } |
1368 | 1368 | |
1369 | +/* This action is used for undoing "cell_flexibility = false" */ | |
1370 | +static int | |
1371 | +s_MolActionSetBoxForFrames(Molecule *mol, MolAction *action, MolAction **actp) | |
1372 | +{ | |
1373 | + Int i, n1, n2; | |
1374 | + Vector *vp1, *vp2; | |
1375 | + n2 = MoleculeGetNumberOfFrames(mol); | |
1376 | + if (n2 == 0 || mol->cell == NULL) | |
1377 | + return 0; /* Do nothing */ | |
1378 | + n1 = action->args[0].u.arval.nitems / 4; | |
1379 | + vp1 = (Vector *)(action->args[0].u.arval.ptr); | |
1380 | + if (mol->nframe_cells < n2) { | |
1381 | + /* Expand the array before processing */ | |
1382 | + i = mol->nframe_cells * 4; | |
1383 | + AssignArray(&(mol->frame_cells), &(mol->nframe_cells), sizeof(Vector) * 4, n2 - 1, NULL); | |
1384 | + while (i < n2 * 4) { | |
1385 | + /* Copy the current cell */ | |
1386 | + mol->frame_cells[i++] = mol->cell->axes[0]; | |
1387 | + mol->frame_cells[i++] = mol->cell->axes[1]; | |
1388 | + mol->frame_cells[i++] = mol->cell->axes[2]; | |
1389 | + mol->frame_cells[i++] = mol->cell->origin; | |
1390 | + } | |
1391 | + } | |
1392 | + | |
1393 | + vp2 = (Vector *)malloc(sizeof(Vector) * n2 * 4); | |
1394 | + memmove(vp2, mol->frame_cells, sizeof(Vector) * n2 * 4); | |
1395 | + memmove(mol->frame_cells, vp1, sizeof(Vector) * 4 * (n1 < n2 ? n1 : n2)); | |
1396 | + *actp = MolActionNew(gMolActionSetBoxForFrames, n2 * 4, vp2); | |
1397 | + free(vp2); | |
1398 | + | |
1399 | + /* Set the current cell (no change on the periodic flags) */ | |
1400 | + vp2 = mol->frame_cells + mol->cframe * 4; | |
1401 | + MoleculeSetPeriodicBox(mol, vp2, vp2 + 1, vp2 + 2, vp2 + 3, mol->cell->flags); | |
1402 | + | |
1403 | + return 0; | |
1404 | +} | |
1405 | + | |
1369 | 1406 | static int |
1370 | 1407 | s_MolActionSetCellFlexibility(Molecule *mol, MolAction *action, MolAction **actp) |
1371 | 1408 | { |
1372 | - Int n1, n2, i; | |
1373 | - if (action == NULL) { | |
1374 | - /* Disable cell flexibility */ | |
1375 | - if (mol->frame_cells == NULL) | |
1376 | - return 0; /* Do nothing */ | |
1377 | - *actp = MolActionNew(gMolActionEnableCellFlexibility, mol->nframes * 4, mol->frame_cells); | |
1409 | + Int n1; | |
1410 | + n1 = action->args[0].u.ival; | |
1411 | + if ((n1 != 0) == (mol->useFlexibleCell != 0)) | |
1412 | + return 0; /* Do nothing */ | |
1413 | + mol->useFlexibleCell = (n1 != 0); | |
1414 | + if (n1 == 0) { | |
1415 | + /* Clear the existing cells, and register undo */ | |
1416 | + if (mol->nframe_cells > 0) { | |
1417 | + MolAction *act2 = MolActionNew(gMolActionSetBoxForFrames, mol->nframe_cells * 4, mol->frame_cells); | |
1418 | + MolActionSetFrame(act2, mol->cframe); | |
1419 | + MolActionCallback_registerUndo(mol, act2); | |
1420 | + MolActionRelease(act2); | |
1421 | + } | |
1378 | 1422 | free(mol->frame_cells); |
1379 | 1423 | mol->frame_cells = NULL; |
1380 | 1424 | mol->nframe_cells = 0; |
1381 | 1425 | } else { |
1382 | - /* Enable cell flexibility, and restore the cell parameters if given */ | |
1383 | - if (mol->cell == NULL) | |
1384 | - return 0; /* If cell is not defined, do nothing */ | |
1385 | - n1 = MoleculeGetNumberOfFrames(mol); | |
1386 | - if (n1 == 0) | |
1387 | - return 0; /* Do nothing */ | |
1388 | - if (mol->frame_cells != NULL) { | |
1389 | - *actp = MolActionNew(gMolActionEnableCellFlexibility, mol->nframes * 4, mol->frame_cells); | |
1390 | - } else { | |
1391 | - *actp = MolActionNew(gMolActionDisableCellFlexibility); | |
1392 | - } | |
1393 | - NewArray(&mol->frame_cells, &mol->nframe_cells, sizeof(Vector) * 4, n1); | |
1394 | - n2 = action->args[0].u.arval.nitems; | |
1395 | - /* Copy the given cell parameters, and if not given copy the current cell parameters */ | |
1396 | - for (i = 0; i < n1 * 4 && i < n2; i++) { | |
1397 | - mol->frame_cells[i] = ((Vector *)(action->args[0].u.arval.ptr))[i]; | |
1398 | - } | |
1399 | - while (i < n1 * 4) { | |
1400 | - mol->frame_cells[i++] = mol->cell->axes[0]; | |
1401 | - mol->frame_cells[i++] = mol->cell->axes[1]; | |
1402 | - mol->frame_cells[i++] = mol->cell->axes[2]; | |
1403 | - mol->frame_cells[i++] = mol->cell->origin; | |
1426 | + /* Allocate cells for all frames and copy the current cell */ | |
1427 | + Int i, nframes = MoleculeGetNumberOfFrames(mol); | |
1428 | + if (nframes != 0 && mol->cell != NULL) { | |
1429 | + if (mol->nframe_cells < nframes) { | |
1430 | + /* Expand the array */ | |
1431 | + AssignArray(&(mol->frame_cells), &(mol->nframe_cells), sizeof(Vector) * 4, nframes - 1, NULL); | |
1432 | + } | |
1433 | + /* Copy the current cell */ | |
1434 | + /* (No undo action is registered; actually, the frame_cells array should be empty) */ | |
1435 | + for (i = 0; i < nframes; i++) { | |
1436 | + mol->frame_cells[i * 4] = mol->cell->axes[0]; | |
1437 | + mol->frame_cells[i * 4 + 1] = mol->cell->axes[1]; | |
1438 | + mol->frame_cells[i * 4 + 2] = mol->cell->axes[2]; | |
1439 | + mol->frame_cells[i * 4 + 3] = mol->cell->origin; | |
1440 | + } | |
1404 | 1441 | } |
1405 | 1442 | } |
1443 | + *actp = MolActionNew(gMolActionSetCellFlexibility, (n1 == 0)); | |
1406 | 1444 | return 0; |
1407 | 1445 | } |
1408 | 1446 |
@@ -1596,14 +1634,12 @@ MolActionPerform(Molecule *mol, MolAction *action) | ||
1596 | 1634 | if (mol->arena != NULL) |
1597 | 1635 | md_set_cell(mol->arena); |
1598 | 1636 | needsSymmetryAmendment = 1; |
1599 | - } else if (strcmp(action->name, gMolActionEnableCellFlexibility) == 0) { | |
1600 | - if ((result = s_MolActionSetCellFlexibility(mol, action, &act2)) != 0) | |
1637 | + } else if (strcmp(action->name, gMolActionSetBoxForFrames) == 0) { | |
1638 | + if ((result = s_MolActionSetBoxForFrames(mol, action, &act2)) != 0) | |
1601 | 1639 | return result; |
1602 | - needsRebuildMDArena = 1; | |
1603 | - } else if (strcmp(action->name, gMolActionDisableCellFlexibility) == 0) { | |
1604 | - if ((result = s_MolActionSetCellFlexibility(mol, NULL, &act2)) != 0) | |
1640 | + } else if (strcmp(action->name, gMolActionSetCellFlexibility) == 0) { | |
1641 | + if ((result = s_MolActionSetCellFlexibility(mol, action, &act2)) != 0) | |
1605 | 1642 | return result; |
1606 | - needsRebuildMDArena = 1; | |
1607 | 1643 | } else if (strcmp(action->name, gMolActionAddParameters) == 0) { |
1608 | 1644 | if ((result = s_MolActionAddParameters(mol, action, &act2)) != 0) |
1609 | 1645 | return result; |
@@ -38,7 +38,6 @@ extern const char *gMolActionAddDihedrals; | ||
38 | 38 | extern const char *gMolActionDeleteDihedrals; |
39 | 39 | extern const char *gMolActionAddImpropers; |
40 | 40 | extern const char *gMolActionDeleteImpropers; |
41 | -/* extern const char *gMolActionReplaceTables; */ | |
42 | 41 | extern const char *gMolActionTranslateAtoms; |
43 | 42 | extern const char *gMolActionRotateAtoms; |
44 | 43 | extern const char *gMolActionTransformAtoms; |
@@ -60,9 +59,8 @@ extern const char *gMolActionAddSymmetryOperation; | ||
60 | 59 | extern const char *gMolActionSetCell; |
61 | 60 | extern const char *gMolActionSetBox; |
62 | 61 | extern const char *gMolActionClearBox; |
63 | -extern const char *gMolActionEnableCellFlexibility; | |
64 | -extern const char *gMolActionDisableCellFlexibility; | |
65 | -/*extern const char *gMolActionSetParameterAttributeForUndo; */ | |
62 | +extern const char *gMolActionSetBoxForFrames; | |
63 | +extern const char *gMolActionSetCellFlexibility; | |
66 | 64 | extern const char *gMolActionAddParameters; |
67 | 65 | extern const char *gMolActionDeleteParameters; |
68 | 66 | extern const char *gMolActionCartesianToXtal; |
@@ -356,6 +356,15 @@ MoleculeInitWithMolecule(Molecule *mp2, const Molecule *mp) | ||
356 | 356 | mp2->syms = (Transform *)calloc(sizeof(Transform), mp2->nsyms); |
357 | 357 | memmove(mp2->syms, mp->syms, sizeof(Transform) * mp2->nsyms); |
358 | 358 | } |
359 | + mp2->useFlexibleCell = mp->useFlexibleCell; | |
360 | + if (mp->nframe_cells > 0) { | |
361 | + if (NewArray(&mp2->frame_cells, &mp2->nframe_cells, sizeof(Vector) * 4, mp->nframe_cells) == NULL) | |
362 | + goto error; | |
363 | + memmove(mp2->frame_cells, mp->frame_cells, sizeof(Vector) * 4 * mp->nframe_cells); | |
364 | + } | |
365 | + | |
366 | + /* FIXME: should bset (basis set info) and elpot be duplicated or not? */ | |
367 | + | |
359 | 368 | if (mp->par != NULL) |
360 | 369 | mp2->par = ParameterDuplicate(mp->par); |
361 | 370 | if (mp->arena != NULL) { |
@@ -1176,6 +1185,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char *errbuf, int errbufsi | ||
1176 | 1185 | } else if (strcmp(buf, "!:frame_periodic_boxes") == 0) { |
1177 | 1186 | Vector vs[5]; |
1178 | 1187 | i = 0; |
1188 | + mp->useFlexibleCell = 1; /* The presence of this block causes asserting this flag */ | |
1179 | 1189 | while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) { |
1180 | 1190 | if (buf[0] == '!') |
1181 | 1191 | continue; |
@@ -3814,7 +3824,7 @@ MoleculeWriteToMbsfFile(Molecule *mp, const char *fname, char *errbuf, int errbu | ||
3814 | 3824 | fprintf(fp, "\n"); |
3815 | 3825 | } |
3816 | 3826 | |
3817 | - if (mp->frame_cells != NULL) { | |
3827 | + if (mp->useFlexibleCell != 0) { | |
3818 | 3828 | fprintf(fp, "!:frame_periodic_boxes\n"); |
3819 | 3829 | fprintf(fp, "! ax ay az; bx by bz; cx cy cz; ox oy oz\n"); |
3820 | 3830 | for (i = 0; i < mp->nframe_cells * 4; i++) { |
@@ -9375,7 +9385,8 @@ MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame, const | ||
9375 | 9385 | vp[j] = ap->r; |
9376 | 9386 | ap->frames = vp; |
9377 | 9387 | } |
9378 | - if (mp->cell != NULL && (mp->frame_cells != NULL || inFrameCell != NULL)) { | |
9388 | + if (mp->cell != NULL && (mp->useFlexibleCell || inFrameCell != NULL)) { | |
9389 | + mp->useFlexibleCell = 1; | |
9379 | 9390 | vp = mp->frame_cells; |
9380 | 9391 | AssignArray(&mp->frame_cells, &mp->nframe_cells, sizeof(Vector) * 4, n_new - 1, NULL); |
9381 | 9392 | if (vp == NULL) { |
@@ -9385,20 +9396,6 @@ MoleculeInsertFrames(Molecule *mp, IntGroup *group, const Vector *inFrame, const | ||
9385 | 9396 | mp->frame_cells[2] = mp->cell->axes[2]; |
9386 | 9397 | mp->frame_cells[3] = mp->cell->origin; |
9387 | 9398 | } |
9388 | -/* vp = mp->frame_cells; | |
9389 | - if (mp->frame_cells == NULL) { | |
9390 | - vp = (Vector *)calloc(sizeof(Vector), n_new * 4); | |
9391 | - vp[0] = mp->cell->axes[0]; | |
9392 | - vp[1] = mp->cell->axes[1]; | |
9393 | - vp[2] = mp->cell->axes[2]; | |
9394 | - vp[3] = mp->cell->origin; | |
9395 | - } else | |
9396 | - vp = (Vector *)realloc(mp->frame_cells, sizeof(Vector) * 4 * n_new); | |
9397 | - if (vp == NULL) { | |
9398 | - __MoleculeUnlock(mp); | |
9399 | - return -1; | |
9400 | - } | |
9401 | - mp->frame_cells = vp; */ | |
9402 | 9399 | } |
9403 | 9400 | |
9404 | 9401 | /* group = [n0..n1-1, n2..n3-1, ...] */ |
@@ -281,6 +281,7 @@ typedef struct Molecule { | ||
281 | 281 | recalculated from the atoms if it is -1 */ |
282 | 282 | Int cframe; /* The current frame number */ |
283 | 283 | |
284 | + Byte useFlexibleCell; | |
284 | 285 | Int nframe_cells; |
285 | 286 | Vector *frame_cells; /* The cell vectors for frames; (nframe_cells*4) array of Vectors */ |
286 | 287 |
@@ -5657,59 +5657,35 @@ s_Molecule_SetBox(VALUE self, VALUE aval) | ||
5657 | 5657 | |
5658 | 5658 | /* |
5659 | 5659 | * call-seq: |
5660 | - * enable_cell_flexibility(array = nil) -> self | |
5660 | + * cell_flexibility -> bool | |
5661 | 5661 | * |
5662 | - * Enable the unit cell flexibility. If array is given, it should be an array of Vector3Ds | |
5663 | - * (or something that can be transformed into Vector3Ds), consisting of avec, bvec, cvec, origin vectors | |
5664 | - * for each frames. If the number of Vectors is less than the number of frames x 4, then the cell parameters | |
5665 | - * for the missing frame is set to the present cell parameters. | |
5666 | - * If unit cell is not defined, an exception is raised. | |
5662 | + * Returns the unit cell is flexible or not | |
5667 | 5663 | */ |
5668 | 5664 | static VALUE |
5669 | -s_Molecule_EnableCellFlexibility(int argc, VALUE *argv, VALUE self) | |
5665 | +s_Molecule_CellFlexibility(VALUE self) | |
5670 | 5666 | { |
5671 | - Molecule *mol; | |
5672 | - VALUE aval; | |
5673 | - Vector *vp; | |
5674 | - Int i, n1; | |
5675 | - Data_Get_Struct(self, Molecule, mol); | |
5667 | + Molecule *mol; | |
5668 | + Data_Get_Struct(self, Molecule, mol); | |
5676 | 5669 | if (mol->cell == NULL) |
5677 | - rb_raise(rb_eMolbyError, "cannot enable cell flexibility because unit cell is not defined yet"); | |
5678 | - rb_scan_args(argc, argv, "01", &aval); | |
5679 | - if (aval == Qnil) { | |
5680 | - n1 = 0; | |
5681 | - vp = NULL; | |
5682 | - } else { | |
5683 | - aval = rb_ary_to_ary(aval); | |
5684 | - n1 = RARRAY_LEN(aval); | |
5685 | - if (n1 == 0) | |
5686 | - vp = NULL; | |
5687 | - else { | |
5688 | - vp = (Vector *)calloc(sizeof(Vector), n1); | |
5689 | - for (i = 0; i < n1; i++) { | |
5690 | - VectorFromValue((RARRAY_PTR(aval))[i], vp + i); | |
5691 | - } | |
5692 | - } | |
5693 | - } | |
5694 | - MolActionCreateAndPerform(mol, gMolActionEnableCellFlexibility, n1, vp); | |
5695 | - free(vp); | |
5696 | - return self; | |
5670 | + return Qfalse; | |
5671 | + if (mol->useFlexibleCell) | |
5672 | + return Qtrue; | |
5673 | + else return Qfalse; | |
5697 | 5674 | } |
5698 | 5675 | |
5699 | 5676 | /* |
5700 | 5677 | * call-seq: |
5701 | - * disable_cell_flexibility -> self | |
5678 | + * self.cell_flexibility = bool | |
5679 | + * set_cell_flexibility(bool) | |
5702 | 5680 | * |
5703 | - * Disable the unit cell flexibility. | |
5681 | + * Change the unit cell is flexible or not | |
5704 | 5682 | */ |
5705 | 5683 | static VALUE |
5706 | -s_Molecule_DisableCellFlexibility(VALUE self) | |
5684 | +s_Molecule_SetCellFlexibility(VALUE self, VALUE arg) | |
5707 | 5685 | { |
5708 | 5686 | Molecule *mol; |
5709 | 5687 | Data_Get_Struct(self, Molecule, mol); |
5710 | - if (mol->cell == NULL) | |
5711 | - return self; | |
5712 | - MolActionCreateAndPerform(mol, gMolActionDisableCellFlexibility); | |
5688 | + MolActionCreateAndPerform(mol, gMolActionSetCellFlexibility, RTEST(arg) != 0); | |
5713 | 5689 | return self; |
5714 | 5690 | } |
5715 | 5691 |
@@ -9505,8 +9481,9 @@ Init_Molby(void) | ||
9505 | 9481 | rb_define_method(rb_cMolecule, "box", s_Molecule_Box, 0); |
9506 | 9482 | rb_define_method(rb_cMolecule, "box=", s_Molecule_SetBox, 1); |
9507 | 9483 | rb_define_method(rb_cMolecule, "set_box", s_Molecule_SetBox, -2); |
9508 | - rb_define_method(rb_cMolecule, "enable_cell_flexibility", s_Molecule_EnableCellFlexibility, -1); | |
9509 | - rb_define_method(rb_cMolecule, "disable_cell_flexibility", s_Molecule_DisableCellFlexibility, 0); | |
9484 | + rb_define_method(rb_cMolecule, "cell_flexibility", s_Molecule_CellFlexibility, 0); | |
9485 | + rb_define_method(rb_cMolecule, "cell_flexibility=", s_Molecule_SetCellFlexibility, 1); | |
9486 | + rb_define_alias(rb_cMolecule, "set_cell_flexibility", "cell_flexibility="); | |
9510 | 9487 | rb_define_method(rb_cMolecule, "symmetry", s_Molecule_Symmetry, 0); |
9511 | 9488 | rb_define_alias(rb_cMolecule, "symmetries", "symmetry"); |
9512 | 9489 | rb_define_method(rb_cMolecule, "nsymmetries", s_Molecule_Nsymmetries, 0); |