1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.xray;
39
40 import static ffx.numerics.math.ScalarMath.b2u;
41 import static ffx.utilities.Constants.KCAL_TO_GRAM_ANG2_PER_PS2;
42 import static ffx.utilities.Constants.kB;
43 import static java.lang.String.format;
44 import static java.util.Arrays.fill;
45
46 import ffx.algorithms.AlgorithmListener;
47 import ffx.algorithms.dynamics.thermostats.Thermostat;
48 import ffx.crystal.Crystal;
49 import ffx.crystal.CrystalPotential;
50 import ffx.numerics.Potential;
51 import ffx.potential.ForceFieldEnergy;
52 import ffx.potential.MolecularAssembly;
53 import ffx.potential.bonded.Atom;
54 import ffx.potential.bonded.Atom.Descriptions;
55 import ffx.potential.bonded.LambdaInterface;
56 import ffx.potential.bonded.Molecule;
57 import ffx.potential.bonded.Residue;
58 import ffx.potential.parameters.ForceField;
59 import ffx.realspace.RealSpaceData;
60 import ffx.realspace.RealSpaceEnergy;
61 import ffx.xray.RefinementMinimize.RefinementMode;
62 import java.util.Arrays;
63 import java.util.List;
64 import java.util.logging.Level;
65 import java.util.logging.Logger;
66 import java.util.stream.Collectors;
67 import java.util.stream.Stream;
68
69
70
71
72
73
74
75
76
77 public class RefinementEnergy implements LambdaInterface, CrystalPotential, AlgorithmListener {
78
79 private static final Logger logger = Logger.getLogger(RefinementEnergy.class.getName());
80
81
82 private final MolecularAssembly[] molecularAssemblies;
83
84 private final DataContainer data;
85
86 private final Atom[] atomArray;
87
88 private final int nAtoms;
89
90 private final Atom[] activeAtomArray;
91
92 private final List<List<Integer>> xIndex;
93
94 private final RefinementMode refinementMode;
95
96 private final double[][] xChemical;
97
98 private final double[][] gChemical;
99
100 protected Thermostat thermostat;
101
102 int nXYZ;
103
104 int nBFactor;
105
106 int nOccupancy;
107
108 private STATE state = STATE.BOTH;
109
110 private CrystalPotential dataEnergy;
111
112 private int n;
113
114 private double kTScale;
115
116 private double[] gXray;
117
118 private double totalEnergy;
119
120 private double[] optimizationScaling;
121
122 private boolean printOnFailure;
123
124
125
126
127
128
129
130 public RefinementEnergy(DataContainer data, RefinementMode refinementMode) {
131 this(data, refinementMode, null);
132 }
133
134
135
136
137
138
139
140
141 @SuppressWarnings("fallthrough")
142 public RefinementEnergy(
143 DataContainer data, RefinementMode refinementMode, double[] optimizationScaling) {
144
145 this.data = data;
146 this.refinementMode = refinementMode;
147 this.optimizationScaling = optimizationScaling;
148 molecularAssemblies = data.getMolecularAssemblies();
149 atomArray = data.getAtomArray();
150 nAtoms = atomArray.length;
151
152 RefinementModel refinementModel = data.getRefinementModel();
153
154
155 ForceField forceField = molecularAssemblies[0].getForceField();
156
157 printOnFailure = forceField.getBoolean("PRINT_ON_FAILURE", true);
158
159
160 int count = 0;
161 int nUse = 0;
162 for (Atom a : atomArray) {
163 if (a.isActive()) {
164 count++;
165 }
166 if (a.getUse()) {
167 nUse++;
168 }
169 }
170 int nActive = count;
171 activeAtomArray = new Atom[count];
172 count = 0;
173 for (Atom a : atomArray) {
174 if (a.isActive()) {
175 activeAtomArray[count++] = a;
176 }
177 }
178
179 xIndex = refinementModel.getxIndex();
180 thermostat = null;
181 kTScale = 1.0;
182
183
184 n = nXYZ = nBFactor = nOccupancy = 0;
185 switch (refinementMode) {
186 case COORDINATES:
187 nXYZ = nActive * 3;
188 break;
189 case COORDINATES_AND_BFACTORS:
190 case COORDINATES_AND_OCCUPANCIES:
191 case COORDINATES_AND_BFACTORS_AND_OCCUPANCIES:
192
193 nXYZ = nActive * 3;
194 case BFACTORS:
195 case OCCUPANCIES:
196 case BFACTORS_AND_OCCUPANCIES:
197 if (data instanceof DiffractionData) {
198 DiffractionData diffractionData = (DiffractionData) data;
199
200 if (refinementMode == RefinementMode.BFACTORS
201 || refinementMode == RefinementMode.BFACTORS_AND_OCCUPANCIES
202 || refinementMode == RefinementMode.COORDINATES_AND_BFACTORS
203 || refinementMode == RefinementMode.COORDINATES_AND_BFACTORS_AND_OCCUPANCIES) {
204 int resnum = -1;
205 int nres = diffractionData.getnResidueBFactor() + 1;
206 for (Atom a : atomArray) {
207
208 if (a.getAtomicNumber() == 1 || !a.isActive()) {
209 continue;
210 }
211 if (a.getAnisou(null) == null) {
212 if (diffractionData.isAddAnisou()) {
213 logger.info(
214 format(" Adding ANISOU to %s.", a.describe(Descriptions.Resnum_Name)));
215 double[] anisou = new double[6];
216 double u = b2u(a.getTempFactor());
217 anisou[0] = anisou[1] = anisou[2] = u;
218 anisou[3] = anisou[4] = anisou[5] = 0.0;
219 a.setAnisou(anisou);
220 nBFactor += 6;
221 } else if (diffractionData.isResidueBFactor()) {
222 if (resnum != a.getResidueNumber()) {
223 if (nres >= diffractionData.getnResidueBFactor()) {
224 nBFactor++;
225 nres = 1;
226 } else {
227 nres++;
228 }
229 resnum = a.getResidueNumber();
230 }
231 } else {
232 nBFactor++;
233 }
234 } else {
235 nBFactor += 6;
236 }
237 }
238 if (diffractionData.isResidueBFactor()) {
239 if (nres < diffractionData.getnResidueBFactor()) {
240 nBFactor--;
241 }
242 }
243 }
244
245
246 if (refinementMode == RefinementMode.OCCUPANCIES
247 || refinementMode == RefinementMode.BFACTORS_AND_OCCUPANCIES
248 || refinementMode == RefinementMode.COORDINATES_AND_OCCUPANCIES
249 || refinementMode == RefinementMode.COORDINATES_AND_BFACTORS_AND_OCCUPANCIES) {
250 for (List<Residue> list : refinementModel.getAltResidues()) {
251 nOccupancy += list.size();
252 }
253 for (List<Molecule> list : refinementModel.getAltMolecules()) {
254 nOccupancy += list.size();
255 }
256 if (nActive != nAtoms) {
257 logger.severe(" Occupancy refinement is not supported with inactive atoms.");
258 }
259 }
260 } else {
261 logger.severe(" Refinement method not supported for this data type!");
262 }
263 break;
264 }
265
266 logger.info(
267 String.format(
268 "\n RefinementEnergy\n Number of atoms:\t\t%d\n Atoms being used: \t\t%d\n Active atoms: \t\t%d",
269 nAtoms, nUse, nActive));
270
271 n = nXYZ + nBFactor + nOccupancy;
272 logger.info(
273 String.format(
274 " Number of variables:\t\t%d (nXYZ %d, nB %d, nOcc %d)\n",
275 n, nXYZ, nBFactor, nOccupancy));
276
277
278 for (MolecularAssembly molecularAssembly : molecularAssemblies) {
279 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
280 if (forceFieldEnergy == null) {
281 forceFieldEnergy = ForceFieldEnergy.energyFactory(molecularAssembly);
282 molecularAssembly.setPotential(forceFieldEnergy);
283 }
284 }
285
286 if (data instanceof DiffractionData) {
287 DiffractionData diffractionData = (DiffractionData) data;
288 if (!diffractionData.getScaled()[0]) {
289 diffractionData.printStats();
290 }
291 dataEnergy = new XRayEnergy(diffractionData, nXYZ, nBFactor, nOccupancy, refinementMode);
292 } else if (data instanceof RealSpaceData) {
293 RealSpaceData realSpaceData = (RealSpaceData) data;
294 dataEnergy = new RealSpaceEnergy(realSpaceData, nXYZ, 0, 0, refinementMode);
295 }
296
297 int assemblySize = molecularAssemblies.length;
298 xChemical = new double[assemblySize][];
299 gChemical = new double[assemblySize][];
300 for (int i = 0; i < assemblySize; i++) {
301 int len = molecularAssemblies[i].getActiveAtomArray().length * 3;
302 xChemical[i] = new double[len];
303 gChemical[i] = new double[len];
304 }
305 }
306
307
308 @Override
309 public boolean algorithmUpdate(MolecularAssembly active) {
310 if (thermostat != null) {
311 kTScale = KCAL_TO_GRAM_ANG2_PER_PS2 / (thermostat.getTargetTemperature() * kB);
312 }
313 logger.info(" kTscale: " + kTScale);
314 logger.info(data.printEnergyUpdate());
315 return true;
316 }
317
318
319 @Override
320 public boolean destroy() {
321 return dataEnergy.destroy();
322 }
323
324
325 @Override
326 public double energy(double[] x) {
327 return energy(x, false);
328 }
329
330
331 @Override
332 public double energy(double[] x, boolean print) {
333 double weight = data.getWeight();
334 double e = 0.0;
335
336 if (thermostat != null) {
337 kTScale = KCAL_TO_GRAM_ANG2_PER_PS2 / (thermostat.getTargetTemperature() * kB);
338 }
339
340 unscaleCoordinates(x);
341
342 int assemblysize = molecularAssemblies.length;
343 switch (refinementMode) {
344 case COORDINATES:
345
346 for (int i = 0; i < assemblysize; i++) {
347 ForceFieldEnergy fe = molecularAssemblies[i].getPotentialEnergy();
348 getAssemblyi(i, x, xChemical[i]);
349 double curE = fe.energy(xChemical[i], print);
350 e += (curE - e) / (i + 1);
351 }
352 double chemE = e;
353
354 e = chemE * kTScale;
355
356
357 double xE = dataEnergy.energy(x, print);
358 e += weight * xE;
359 break;
360 case BFACTORS:
361 case OCCUPANCIES:
362 case BFACTORS_AND_OCCUPANCIES:
363
364 e = dataEnergy.energy(x, print);
365 break;
366 case COORDINATES_AND_BFACTORS:
367 case COORDINATES_AND_OCCUPANCIES:
368 case COORDINATES_AND_BFACTORS_AND_OCCUPANCIES:
369
370 for (int i = 0; i < assemblysize; i++) {
371 ForceFieldEnergy fe = molecularAssemblies[i].getPotentialEnergy();
372 getAssemblyi(i, x, xChemical[i]);
373 double curE = fe.energy(xChemical[i], print);
374 e += (curE - e) / (i + 1);
375 }
376 e += weight * dataEnergy.energy(x, print);
377 break;
378 default:
379 String message = "Unknown refinement mode.";
380 logger.log(Level.SEVERE, message);
381 }
382
383 scaleCoordinates(x);
384
385 totalEnergy = e;
386 return e;
387 }
388
389
390
391
392
393
394 @Override
395 public double energyAndGradient(double[] x, double[] g) {
396 return energyAndGradient(x, g, false);
397 }
398
399
400
401
402
403
404 @Override
405 public double energyAndGradient(double[] x, double[] g, boolean print) {
406 double weight = data.getWeight();
407 double e = 0.0;
408 fill(g, 0.0);
409
410 if (thermostat != null) {
411 kTScale = KCAL_TO_GRAM_ANG2_PER_PS2 / (thermostat.getTargetTemperature() * kB);
412 }
413
414 unscaleCoordinates(x);
415
416 int assemblysize = molecularAssemblies.length;
417 switch (refinementMode) {
418 case COORDINATES:
419
420 for (int i = 0; i < assemblysize; i++) {
421 ForceFieldEnergy fe = molecularAssemblies[i].getPotentialEnergy();
422 getAssemblyi(i, x, xChemical[i]);
423 double curE = fe.energyAndGradient(xChemical[i], gChemical[i], print);
424 e += (curE - e) / (i + 1);
425 setAssemblyi(i, g, gChemical[i]);
426 }
427 double chemE = e;
428
429 e = chemE * kTScale;
430
431 if (assemblysize > 1) {
432 for (int i = 0; i < nXYZ; i++) {
433 g[i] /= assemblysize;
434 }
435 }
436 for (int i = 0; i < nXYZ; i++) {
437 g[i] *= kTScale;
438 }
439
440
441 if (gXray == null || gXray.length != nXYZ) {
442 gXray = new double[nXYZ];
443 }
444 double xE = dataEnergy.energyAndGradient(x, gXray);
445
446 e += weight * xE;
447
448
449 for (int i = 0; i < nXYZ; i++) {
450 g[i] += weight * gXray[i];
451 }
452 break;
453 case BFACTORS:
454 case OCCUPANCIES:
455 case BFACTORS_AND_OCCUPANCIES:
456
457 e = dataEnergy.energyAndGradient(x, g);
458 break;
459 case COORDINATES_AND_BFACTORS:
460 case COORDINATES_AND_OCCUPANCIES:
461 case COORDINATES_AND_BFACTORS_AND_OCCUPANCIES:
462
463 for (int i = 0; i < assemblysize; i++) {
464 ForceFieldEnergy fe = molecularAssemblies[i].getPotentialEnergy();
465 getAssemblyi(i, x, xChemical[i]);
466 double curE = fe.energyAndGradient(xChemical[i], gChemical[i], print);
467 e += (curE - e) / (i + 1);
468 setAssemblyi(i, g, gChemical[i]);
469 }
470
471 if (assemblysize > 1) {
472 for (int i = 0; i < nXYZ; i++) {
473 g[i] /= assemblysize;
474 }
475 }
476
477
478 if (gXray == null || gXray.length != n) {
479 gXray = new double[n];
480 }
481 e += weight * dataEnergy.energyAndGradient(x, gXray);
482
483
484 for (int i = 0; i < nXYZ; i++) {
485 g[i] += weight * gXray[i];
486 }
487
488
489 if (n > nXYZ) {
490 for (int i = nXYZ; i < n; i++) {
491 g[i] = weight * gXray[i];
492 }
493 }
494 break;
495 default:
496 String message = "Unknown refinement mode.";
497 logger.log(Level.SEVERE, message);
498 }
499
500 scaleCoordinatesAndGradient(x, g);
501
502 totalEnergy = e;
503 return e;
504 }
505
506
507 @Override
508 public double[] getAcceleration(double[] acceleration) {
509 if (this.nBFactor > 0 || this.nOccupancy > 0) {
510 throw new UnsupportedOperationException("Not supported yet.");
511 }
512 int n = getNumberOfVariables();
513 if (acceleration == null || acceleration.length < n) {
514 acceleration = new double[n];
515 }
516 int index = 0;
517 double[] a = new double[3];
518 for (int i = 0; i < nAtoms; i++) {
519 if (atomArray[i].isActive()) {
520 atomArray[i].getAcceleration(a);
521 acceleration[index++] = a[0];
522 acceleration[index++] = a[1];
523 acceleration[index++] = a[2];
524 }
525 }
526 return acceleration;
527 }
528
529
530
531
532
533
534 public Atom[] getActiveAtoms() {
535 return activeAtomArray;
536 }
537
538
539 @Override
540 public double[] getCoordinates(double[] parameters) {
541 return dataEnergy.getCoordinates(parameters);
542 }
543
544
545 @Override
546 public Crystal getCrystal() {
547 return dataEnergy.getCrystal();
548 }
549
550
551 @Override
552 public void setCrystal(Crystal crystal) {
553 logger.severe(" RefinementEnergy does implement setCrystal yet.");
554 }
555
556
557
558
559
560
561 public CrystalPotential getDataEnergy() {
562 return dataEnergy;
563 }
564
565
566 @Override
567 public STATE getEnergyTermState() {
568 return state;
569 }
570
571
572 @Override
573 public void setEnergyTermState(STATE state) {
574 this.state = state;
575 for (MolecularAssembly molecularAssembly : molecularAssemblies) {
576 ForceFieldEnergy fe = molecularAssembly.getPotentialEnergy();
577 fe.setEnergyTermState(state);
578 }
579 dataEnergy.setEnergyTermState(state);
580 }
581
582
583
584
585
586
587 public double getKTScale() {
588 return this.kTScale;
589 }
590
591
592
593
594
595
596 public void setKTScale(double ktscale) {
597 this.kTScale = ktscale;
598 }
599
600
601 @Override
602 public double getLambda() {
603 double lambda = 1.0;
604 if (data instanceof DiffractionData) {
605 XRayEnergy xRayEnergy = (XRayEnergy) dataEnergy;
606 lambda = xRayEnergy.getLambda();
607 } else if (data instanceof RealSpaceData) {
608 RealSpaceEnergy realSpaceEnergy = (RealSpaceEnergy) dataEnergy;
609 lambda = realSpaceEnergy.getLambda();
610 }
611 return lambda;
612 }
613
614
615 @Override
616 public void setLambda(double lambda) {
617 for (MolecularAssembly molecularAssembly : molecularAssemblies) {
618 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
619 forceFieldEnergy.setLambda(lambda);
620 }
621 if (data instanceof DiffractionData) {
622 XRayEnergy xRayEnergy = (XRayEnergy) dataEnergy;
623 xRayEnergy.setLambda(lambda);
624 } else if (data instanceof RealSpaceData) {
625 RealSpaceEnergy realSpaceEnergy = (RealSpaceEnergy) dataEnergy;
626 realSpaceEnergy.setLambda(lambda);
627 }
628 }
629
630
631 @Override
632 public double[] getMass() {
633 return dataEnergy.getMass();
634 }
635
636
637 @Override
638 public int getNumberOfVariables() {
639 return dataEnergy.getNumberOfVariables();
640 }
641
642
643 @Override
644 public double[] getPreviousAcceleration(double[] previousAcceleration) {
645 if (this.nBFactor > 0 || this.nOccupancy > 0) {
646 throw new UnsupportedOperationException("Not supported yet.");
647 }
648 int n = getNumberOfVariables();
649 if (previousAcceleration == null || previousAcceleration.length < n) {
650 previousAcceleration = new double[n];
651 }
652 int index = 0;
653 double[] a = new double[3];
654 for (int i = 0; i < nAtoms; i++) {
655 if (atomArray[i].isActive()) {
656 atomArray[i].getPreviousAcceleration(a);
657 previousAcceleration[index++] = a[0];
658 previousAcceleration[index++] = a[1];
659 previousAcceleration[index++] = a[2];
660 }
661 }
662 return previousAcceleration;
663 }
664
665
666
667
668
669
670 public boolean getPrintOnFailure() {
671 return printOnFailure;
672 }
673
674
675 @Override
676 public double[] getScaling() {
677 return optimizationScaling;
678 }
679
680
681 @Override
682 public void setScaling(double[] scaling) {
683 optimizationScaling = scaling;
684 }
685
686
687
688
689
690
691 public Thermostat getThermostat() {
692 return thermostat;
693 }
694
695
696
697
698
699
700 public void setThermostat(Thermostat thermostat) {
701 this.thermostat = thermostat;
702 }
703
704
705 @Override
706 public double getTotalEnergy() {
707 return totalEnergy;
708 }
709
710 @Override
711 public List<Potential> getUnderlyingPotentials() {
712 Stream<Potential> directPEs =
713 Arrays.stream(molecularAssemblies).map(MolecularAssembly::getPotentialEnergy);
714 Stream<Potential> allPEs =
715 Arrays.stream(molecularAssemblies)
716 .map(MolecularAssembly::getPotentialEnergy)
717 .map(Potential::getUnderlyingPotentials)
718 .flatMap(List::stream);
719 return Stream.concat(directPEs, allPEs).collect(Collectors.toList());
720 }
721
722
723
724
725
726
727 @Override
728 public VARIABLE_TYPE[] getVariableTypes() {
729 return dataEnergy.getVariableTypes();
730 }
731
732
733 @Override
734 public double[] getVelocity(double[] velocity) {
735 if (this.nBFactor > 0 || this.nOccupancy > 0) {
736 throw new UnsupportedOperationException("Not supported yet.");
737 }
738 int n = getNumberOfVariables();
739 if (velocity == null || velocity.length < n) {
740 velocity = new double[n];
741 }
742 int index = 0;
743 double[] v = new double[3];
744 for (int i = 0; i < nAtoms; i++) {
745 Atom a = atomArray[i];
746 if (a.isActive()) {
747 a.getVelocity(v);
748 velocity[index++] = v[0];
749 velocity[index++] = v[1];
750 velocity[index++] = v[2];
751 }
752 }
753 return velocity;
754 }
755
756
757
758
759
760
761 public double getXWeight() {
762 return data.getWeight();
763 }
764
765
766 @Override
767 public double getd2EdL2() {
768 double d2EdL2 = 0.0;
769 if (thermostat != null) {
770 kTScale = KCAL_TO_GRAM_ANG2_PER_PS2 / (thermostat.getTargetTemperature() * kB);
771 }
772 int assemblysize = molecularAssemblies.length;
773
774
775 for (int i = 0; i < assemblysize; i++) {
776 ForceFieldEnergy forceFieldEnergy = molecularAssemblies[i].getPotentialEnergy();
777 double curE = forceFieldEnergy.getd2EdL2();
778 d2EdL2 += (curE - d2EdL2) / (i + 1);
779 }
780 d2EdL2 *= kTScale;
781
782
783 return d2EdL2;
784 }
785
786
787 @Override
788 public double getdEdL() {
789 double dEdL = 0.0;
790 if (thermostat != null) {
791 kTScale = KCAL_TO_GRAM_ANG2_PER_PS2 / (thermostat.getTargetTemperature() * kB);
792 }
793 int assemblysize = molecularAssemblies.length;
794
795
796 for (int i = 0; i < assemblysize; i++) {
797 ForceFieldEnergy forceFieldEnergy = molecularAssemblies[i].getPotentialEnergy();
798 double curdEdL = forceFieldEnergy.getdEdL();
799 dEdL += (curdEdL - dEdL) / (i + 1);
800 }
801 dEdL *= kTScale;
802 double weight = data.getWeight();
803 if (data instanceof DiffractionData) {
804 XRayEnergy xRayEnergy = (XRayEnergy) dataEnergy;
805 dEdL += weight * xRayEnergy.getdEdL();
806 } else if (data instanceof RealSpaceData) {
807 RealSpaceEnergy realSpaceEnergy = (RealSpaceEnergy) dataEnergy;
808 dEdL += weight * realSpaceEnergy.getdEdL();
809 }
810 return dEdL;
811 }
812
813
814 @Override
815 public void getdEdXdL(double[] gradient) {
816 double weight = data.getWeight();
817 if (thermostat != null) {
818 kTScale = KCAL_TO_GRAM_ANG2_PER_PS2 / (thermostat.getTargetTemperature() * kB);
819 }
820 int assemblysize = molecularAssemblies.length;
821
822
823 for (int i = 0; i < assemblysize; i++) {
824 ForceFieldEnergy forcefieldEnergy = molecularAssemblies[i].getPotentialEnergy();
825 Arrays.fill(gChemical[i], 0.0);
826 forcefieldEnergy.getdEdXdL(gChemical[i]);
827 }
828 for (int i = 0; i < assemblysize; i++) {
829 for (int j = 0; j < nXYZ; j++) {
830 gradient[j] += gChemical[i][j];
831 }
832 }
833
834
835 if (assemblysize > 1) {
836 for (int i = 0; i < nXYZ; i++) {
837 gradient[i] /= assemblysize;
838 }
839 }
840 for (int i = 0; i < nXYZ; i++) {
841 gradient[i] *= kTScale;
842 }
843
844
845 if (gXray == null || gXray.length != nXYZ) {
846 gXray = new double[nXYZ];
847 } else {
848 for (int j = 0; j < nXYZ; j++) {
849 gXray[j] = 0.0;
850 }
851 }
852 if (data instanceof DiffractionData) {
853 XRayEnergy xRayEnergy = (XRayEnergy) dataEnergy;
854 xRayEnergy.getdEdXdL(gXray);
855 } else if (data instanceof RealSpaceData) {
856 RealSpaceEnergy realSpaceEnergy = (RealSpaceEnergy) dataEnergy;
857 realSpaceEnergy.getdEdXdL(gXray);
858 }
859
860
861 for (int i = 0; i < nXYZ; i++) {
862 gradient[i] += weight * gXray[i];
863 }
864 }
865
866
867 @Override
868 public void setAcceleration(double[] acceleration) {
869 if (this.nBFactor > 0 || this.nOccupancy > 0) {
870 throw new UnsupportedOperationException("Not supported yet.");
871 }
872 if (acceleration == null) {
873 return;
874 }
875 int index = 0;
876 double[] accel = new double[3];
877 for (int i = 0; i < nAtoms; i++) {
878 if (atomArray[i].isActive()) {
879 accel[0] = acceleration[index++];
880 accel[1] = acceleration[index++];
881 accel[2] = acceleration[index++];
882 atomArray[i].setAcceleration(accel);
883 }
884 }
885 }
886
887
888 @Override
889 public void setPreviousAcceleration(double[] previousAcceleration) {
890 if (this.nBFactor > 0 || this.nOccupancy > 0) {
891 throw new UnsupportedOperationException("Not supported yet.");
892 }
893 if (previousAcceleration == null) {
894 return;
895 }
896 int index = 0;
897 double[] prev = new double[3];
898 for (int i = 0; i < nAtoms; i++) {
899 if (atomArray[i].isActive()) {
900 prev[0] = previousAcceleration[index++];
901 prev[1] = previousAcceleration[index++];
902 prev[2] = previousAcceleration[index++];
903 atomArray[i].setPreviousAcceleration(prev);
904 }
905 }
906 }
907
908
909
910
911
912
913
914
915
916
917
918 public void setPrintOnFailure(boolean onFail, boolean override) {
919 if (override) {
920
921 printOnFailure = onFail;
922 } else {
923 try {
924 molecularAssemblies[0].getForceField().getBoolean("PRINT_ON_FAILURE");
925
926
927
928
929
930 } catch (Exception ex) {
931 printOnFailure = onFail;
932 }
933 }
934 }
935
936
937 @Override
938 public void setVelocity(double[] velocity) {
939 if (this.nBFactor > 0 || this.nOccupancy > 0) {
940 throw new UnsupportedOperationException("Not supported yet.");
941 }
942 if (velocity == null) {
943 return;
944 }
945 int index = 0;
946 double[] vel = new double[3];
947 for (int i = 0; i < nAtoms; i++) {
948 if (atomArray[i].isActive()) {
949 vel[0] = velocity[index++];
950 vel[1] = velocity[index++];
951 vel[2] = velocity[index++];
952 atomArray[i].setVelocity(vel);
953 }
954 }
955 }
956
957
958
959
960
961
962
963
964
965 private void getAssemblyi(int i, double[] x, double[] xChem) {
966 assert (x != null && xChem != null);
967 for (int j = 0; j < xChem.length; j += 3) {
968 int index = j / 3;
969
970 int aindex = xIndex.get(i).get(index) * 3;
971 xChem[j] = x[aindex];
972 xChem[j + 1] = x[aindex + 1];
973 xChem[j + 2] = x[aindex + 2];
974 }
975 }
976
977
978
979
980
981
982
983
984
985 private void setAssemblyi(int i, double[] x, double[] xChem) {
986 assert (x != null && xChem != null);
987 for (int j = 0; j < xChem.length; j += 3) {
988 int index = j / 3;
989
990 int aindex = xIndex.get(i).get(index) * 3;
991 x[aindex] += xChem[j];
992 x[aindex + 1] += xChem[j + 1];
993 x[aindex + 2] += xChem[j + 2];
994 }
995 }
996 }