File size: 33,482 Bytes
10f2621
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
/**
 * @defgroup  Frontend  High-level front-end routines
 */

/**
 *  @file    routines.h
 *  @author  Nathan Baker
 *  @brief   Header file for front end auxiliary routines
 *  @ingroup  Frontend
 *  @version $Id$
 *  @attention
 *  @verbatim
 *
 * APBS -- Adaptive Poisson-Boltzmann Solver
 *
 *  Nathan A. Baker (nathan.baker@pnnl.gov)
 *  Pacific Northwest National Laboratory
 *
 *  Additional contributing authors listed in the code documentation.
 *
 * Copyright (c) 2010-2020 Battelle Memorial Institute. Developed at the
 * Pacific Northwest National Laboratory, operated by Battelle Memorial
 * Institute, Pacific Northwest Division for the U.S. Department of Energy.
 *
 * Portions Copyright (c) 2002-2010, Washington University in St. Louis.
 * Portions Copyright (c) 2002-2010, Nathan A. Baker.
 * Portions Copyright (c) 1999-2002, The Regents of the University of
 * California.
 * Portions Copyright (c) 1995, Michael Holst.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the developer nor the names of its contributors may be
 * used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @endverbatim
 */

#ifndef _APBSROUTINES_H_
#define _APBSROUTINES_H_

#include "apbs.h"

#ifdef HAVE_MC
#    include "mc/mc.h"
#    include "fem/vfetk.h"
#endif
#ifdef HAVE_MCX
#    include "mcx/mcx.h"
#endif

#ifdef ENABLE_BEM
  #include "TABIPBWrap.h"
#endif

#ifdef ENABLE_GEOFLOW
  #include "GeometricFlowWrap.h"
  #include "geoflow/geoflow_wrap_apbs.h"
#endif

#if defined(ENABLE_PBAM) || defined(ENABLE_PBSAM)
  #include "PBAMWrap.h"
#endif

#ifdef ENABLE_PBSAM
  #include "PBSAMWrap.h"
#endif

/**
 * @brief  Return code for APBS during failure
 * @ingroup  Frontend */
#define APBSRC 13

/**
 * @brief  Structure to hold atomic forces
 * @ingroup  Frontend
 * @author  Nathan Baker */
struct AtomForce {
   double ibForce[3];  /**< Ion-boundary force */
   double qfForce[3];  /**< Charge-field force */
   double dbForce[3];  /**< Dielectric boundary force */
   double sasaForce[3];  /**< SASA force (coupled to gamma) */
   double savForce[3];  /**< SAV force (coupled to press) */
   double wcaForce[3];  /**< WCA integral force (coupled to bconc) */
};

/**
 * @brief  Define AtomForce type
 * @ingroup  Frontend */
typedef struct AtomForce AtomForce;

/**
 * @brief  Loads and returns parameter object
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @returns  Pointer to parameter object or NULL */
VEXTERNC Vparam* loadParameter(
                               NOsh *nosh  /**< Pointer to NOsh object with input
                               file information */
                               );

/**
 * @brief  Load the molecules given in NOsh into atom lists
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @returns  1 if successful, 0 otherwise */
VEXTERNC int loadMolecules(
                           NOsh *nosh, /**< NOsh object with input file information */
                           Vparam *param,  /**< NULL (if PQR files only) or pointer
                           to parameter object */
                           Valist *alist[NOSH_MAXMOL]  /**< List of atom list objects
                           (to be populated) */
                           );

/**
 * @brief  Destroy the loaded molecules
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  alist  List of atom list objects */
VEXTERNC void killMolecules(NOsh *nosh, Valist *alist[NOSH_MAXMOL]);

/**
 * @brief  Load the dielectric maps given in NOsh into grid objects
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  dielXMap  List of x-shifted dielectric maps
 * @param  dielYMap  List of y-shifted dielectric maps
 * @param  dielZMap  List of x-shifted dielectric maps
 * @returns  1 if successful, 0 otherwise */
VEXTERNC int loadDielMaps(NOsh *nosh,
                          Vgrid *dielXMap[NOSH_MAXMOL],
                          Vgrid *dielYMap[NOSH_MAXMOL],
                          Vgrid *dielZMap[NOSH_MAXMOL]
                         );

/**
 * @brief  Destroy the loaded dielectric
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  dielXMap  List of x-shifted dielectric maps
 * @param  dielYMap  List of y-shifted dielectric maps
 * @param  dielZMap  List of x-shifted dielectric maps */
VEXTERNC void killDielMaps(NOsh *nosh, Vgrid *dielXMap[NOSH_MAXMOL],
  Vgrid *dielYMap[NOSH_MAXMOL], Vgrid *dielZMap[NOSH_MAXMOL]);

/**
 * @brief  Load the kappa maps given in NOsh into grid objects
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  kappa  List of kappa maps
 * @returns  1 if successful, 0 otherwise */
VEXTERNC int loadKappaMaps(NOsh *nosh, Vgrid *kappa[NOSH_MAXMOL]);

/**
 * @brief  Destroy the loaded kappa maps
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  kappa  List of kappa maps */
VEXTERNC void killKappaMaps(NOsh *nosh, Vgrid *kappa[NOSH_MAXMOL]);

/**
 * @brief  Load the potential maps given in NOsh into grid objects
 * @ingroup  Frontend
 * @author  David Gohara
 * @param  nosh  NOsh object with input file information
 * @param  pot  List of potential maps
 * @returns  1 if successful, 0 otherwise */
VEXTERNC int loadPotMaps(NOsh *nosh, Vgrid *pot[NOSH_MAXMOL]);

/**
 * @brief  Destroy the loaded potential maps
 * @ingroup  Frontend
 * @author  David Gohara
 * @param  nosh  NOsh object with input file information
 * @param  pot  List of potential maps */
VEXTERNC void killPotMaps(NOsh *nosh, Vgrid *pot[NOSH_MAXMOL]);

/**
 * @brief  Load the charge maps given in NOsh into grid objects
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  charge  List of kappa maps
 * @returns  1 if successful, 0 otherwise */
VEXTERNC int loadChargeMaps(NOsh *nosh, Vgrid *charge[NOSH_MAXMOL]);

/**
 * @brief  Destroy the loaded charge maps
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  nosh  NOsh object with input file information
 * @param  charge  List of charge maps */
VEXTERNC void killChargeMaps(NOsh *nosh, Vgrid *charge[NOSH_MAXMOL]);

/**
 * @brief  Print out generic PBE params loaded from input
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  pbeparm  PBEparm object */
VEXTERNC void printPBEPARM(PBEparm *pbeparm);

/**
 * @brief  Print out MG-specific params loaded from input
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  realCenter  Center of mesh for actual calculation
 * @param  mgparm  MGparm object */
VEXTERNC void printMGPARM(MGparm *mgparm, double realCenter[3]);

/**
 * @brief  Initialize an MG calculation
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @return  1 if succesful, 0 otherwise */
VEXTERNC int initMG(
                    int icalc,  /**< Index of calculation in pmg/pmpg arrays */
                    NOsh *nosh,  /**< Object with parsed input file parameters */
                    MGparm *mgparm,  /**< Object with MG-specific parameters */
                    PBEparm *pbeparm,  /**< Object with generic PBE parameters  */
                    double realCenter[3],  /**< The actual center of the current mesh */
                    Vpbe *pbe[NOSH_MAXCALC],  /**< Array of Vpbe objects (one for each calc) */
                    Valist *alist[NOSH_MAXMOL],  /**< Array of atom lists */
                    Vgrid *dielXMap[NOSH_MAXMOL],  /**< Array of x-shifted dielectric maps */
                    Vgrid *dielYMap[NOSH_MAXMOL],  /**< Array of y-shifted dielectric maps */
                    Vgrid *dielZMap[NOSH_MAXMOL],  /**< Array of z-shifted dielectric maps */
                    Vgrid *kappaMap[NOSH_MAXMOL],  /**< Array of kappa maps  */
                    Vgrid *chargeMap[NOSH_MAXMOL],  /**< Array of charge maps */
                    Vpmgp *pmgp[NOSH_MAXCALC],  /**< Array of MG parameter objects (one for each calc) */
                    Vpmg *pmg[NOSH_MAXCALC],  /**< Array of MG objects (one for each calc) */
                    Vgrid *potMap[NOSH_MAXMOL]  /**< Array of potential maps  */
                    );

/**
 * @brief  Kill structures initialized during an MG calculation
 * @ingroup  Frontend
 * @author  Nathan Baker
 */
VEXTERNC void killMG(
                     NOsh *nosh,  /** Object with parsed input file parameters */
                     Vpbe *pbe[NOSH_MAXCALC],  /** Array of Vpbe objects for each calc */
                     Vpmgp *pmgp[NOSH_MAXCALC],  /** Array of MG parameter objects for each calc */
                     Vpmg *pmg[NOSH_MAXCALC]  /** Array of MG objects for each calc */
);

/**
 * @brief  Solve the PBE with MG
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param nosh  Object with parsed input file parameters
 * @param pmg  MG objects for this calculation
 * @param type  Type of MG calculation
 * @return  1 if successful, 0 otherwise */
VEXTERNC int solveMG(NOsh *nosh, Vpmg *pmg, MGparm_CalcType type);

/**
 * @brief  Set MG partitions for calculating observables and performing I/O
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param nosh  Object with parsed input file parameters
 * @param mgparm  MG parameters from input file
 * @param pmg  MG object
 * @return  1 if successful, 0 otherwise */
VEXTERNC int setPartMG(NOsh *nosh, MGparm *mgparm, Vpmg *pmg);

/**
 * @brief  Calculate electrostatic energies from MG solution
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param nosh  Object with parsed input file parameters
 * @param icalc  Index of calculation
 * @param pmg  MG object
 * @param nenergy  Set to number of entries in energy arrays
 * @param totEnergy  Set to total energy (in kT)
 * @param qfEnergy  Set to charge-potential energy (in kT)
 * @param qmEnergy  Set to mobile ion energy (in kT)
 * @param dielEnergy  Set to polarization energy (in kT)
 * @return  1 if successful, 0 otherwise */
VEXTERNC int energyMG(NOsh* nosh, int icalc, Vpmg *pmg,
  int *nenergy, double *totEnergy, double *qfEnergy, double *qmEnergy,
  double *dielEnergy);

/**
 * @brief  Kill arrays allocated for energies
 * @ingroup  Frontend
 * @author  Nathan Baker */
VEXTERNC void killEnergy();

/**
 * @brief  Calculate forces from MG solution
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  mem  Memory management object
 * @param  nosh  Parameters from input file
 * @param  pbeparm  Generic PBE parameters
 * @param  mgparm  MG-specific parmaeters
 * @param pmg  MG object
 * @param nforce  Set to number of forces in arrays
 * @param  atomForce  List of atom forces
 * @param  alist  List of atom lists
 * @return  1 if successful, 0 otherwise */
VEXTERNC int forceMG(Vmem *mem, NOsh *nosh, PBEparm *pbeparm,  MGparm *mgparm,
  Vpmg *pmg, int *nforce, AtomForce **atomForce, Valist *alist[NOSH_MAXMOL]);

/**
 * @brief  Free memory from MG force calculation
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  mem  Memory management object
 * @param  nosh  Parameters from input file
 * @param  nforce  Number of forces in arrays
 * @param  atomForce  List of atom forces */
VEXTERNC void killForce(Vmem *mem, NOsh *nosh, int nforce[NOSH_MAXCALC],
  AtomForce *atomForce[NOSH_MAXCALC]);

/**
 * @brief Store energy in arrays for future use
 * @ingroup Frontend
 * @author Todd Dolinsky */
VEXTERNC void storeAtomEnergy(
        Vpmg *pmg, /**< MG object */
        int icalc, /**< Calculation number */
        double **atomEnergy, /**< Pointer to storage array of doubles */
        int *nenergy /**< Stores number of atoms per calc */
        );

/**
 * @brief Write out information to a flat file
 * @ingroup Frontend
 * @author  Todd Dolinsky
 * @param nosh  Parameters from input file
 * @param com   The communications object
 * @param fname The target XML file name
 * @param totEnergy An array with per-calc total energies (in kT)
 * @param qfEnergy  An array with per-calc charge-potential energies (in kT)
 * @param qmEnergy  An array with per-calc mobile energies (in kT)
 * @param dielEnergy  An array with per-calc polarization energies (in kT)
 * @param nenergy  An array containing the number of atoms per-calc
 * @param atomEnergy An array containing per-atom energies (in KT) per calc
 * @param nforce  An array containing the number of forces calculated per-calc
 * @param atomForce An array containing per-atom forces per calc
 * @return 1 if successful, 0 otherwise */
VEXTERNC int writedataFlat(NOsh *nosh, Vcom *com, const char *fname,
  double totEnergy[NOSH_MAXCALC], double qfEnergy[NOSH_MAXCALC],
  double qmEnergy[NOSH_MAXCALC], double dielEnergy[NOSH_MAXCALC],
  int nenergy[NOSH_MAXCALC], double *atomEnergy[NOSH_MAXCALC],
  int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC]);

/**
 * @brief Write out information to an XML file
 * @ingroup Frontend
 * @author  Todd Dolinsky
 * @param nosh  Parameters from input file
 * @param com   The communications object
 * @param fname The target XML file name
 * @param totEnergy An array with per-calc total energies (in kT)
 * @param qfEnergy  An array with per-calc charge-potential energies (in kT)
 * @param qmEnergy  An array with per-calc mobile energies (in kT)
 * @param dielEnergy  An array with per-calc polarization energies (in kT)
 * @param nenergy  An array containing the number of atoms per-calc
 * @param atomEnergy An array containing per-atom energies (in KT) per calc
 * @param nforce  An array containing the number of forces calculated per-calc
 * @param atomForce An array containing per-atom forces per calc
 * @return 1 if successful, 0 otherwise */
VEXTERNC int writedataXML(NOsh *nosh, Vcom *com, const char *fname,
  double totEnergy[NOSH_MAXCALC], double qfEnergy[NOSH_MAXCALC],
  double qmEnergy[NOSH_MAXCALC], double dielEnergy[NOSH_MAXCALC],
  int nenergy[NOSH_MAXCALC], double *atomEnergy[NOSH_MAXCALC],
  int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC]);

/**
 * @brief  Write out observables from MG calculation to file
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  rank  Processor rank (if parallel calculation)
 * @param  nosh  Parameters from input file
 * @param  pbeparm  Generic PBE parameters
 * @param pmg  MG object
 * @return  1 if successful, 0 otherwise */
VEXTERNC int writedataMG(int rank, NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg);

/**
 * @brief  Write out operator matrix from MG calculation to file
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  rank  Processor rank (if parallel calculation)
 * @param  nosh  Parameters from input file
 * @param  pbeparm  Generic PBE parameters
 * @param pmg  MG object
 * @return  1 if successful, 0 otherwise */
VEXTERNC int writematMG(int rank, NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg);

/**
* @brief  Access net local energy
 * @ingroup  Frontend
 * @author  Justin Xiang
 * @param  com  Communications object
 * @param  nosh  Parameters from input file
 * @param  totEnergy  Array of energies from different calculations
 * @param  iprint  Index of energy statement to print
 * @return  Net local energy */
VEXTERNC double returnEnergy(Vcom *com, NOsh *nosh, double totEnergy[NOSH_MAXCALC], int iprint);

/**
* @brief  Combine and pretty-print energy data (deprecated...see printElecEnergy)
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @return  1 if successful, 0 otherwise */
VEXTERNC int printEnergy(
                         Vcom *com, /** Communications object */
                         NOsh *nosh, /** Parameters from input file */
                         double totEnergy[NOSH_MAXCALC], /** Array of energies
                         from different calculations */
                         int iprint /** Index of energy statement to print */
                         );

/**
* @brief  Combine and pretty-print energy data
* @ingroup  Frontend
* @author  David Gohara
* @return  1 if successful, 0 otherwise */
VEXTERNC int printElecEnergy(
                         Vcom *com, /** Communications object */
                         NOsh *nosh, /** Parameters from input file */
                         double totEnergy[NOSH_MAXCALC], /** Array of energies
                             from different calculations */
                         int iprint /** Index of energy statement to print */
                         );

/**
* @brief  Combine and pretty-print energy data
* @ingroup  Frontend
* @author  David Gohara
* @return  1 if successful, 0 otherwise */
VEXTERNC int printApolEnergy(
                         NOsh *nosh,  /**< Parameters from input file */
                         int iprint  /**< Index of energy statement to print */
                         );

/**
 * @brief  Combine and pretty-print force data (deprecated...see printElecForce)
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @return  1 if successful, 0 otherwise */
VEXTERNC int printForce(
                        Vcom *com, /** Communications object */
                        NOsh *nosh, /** Parameters from input file */
                        int nforce[NOSH_MAXCALC], /** Number of forces calculated */
                        AtomForce *atomForce[NOSH_MAXCALC], /** Array of force structures */
                        int i /** Index of force statement to print */
                        );

/**
* @brief  Combine and pretty-print force data
* @ingroup  Frontend
* @author  David Gohara
* @return  1 if successful, 0 otherwise */
VEXTERNC int printElecForce(
                            Vcom *com, /** Communications object */
                            NOsh *nosh, /** Parameters from input file */
                            int nforce[NOSH_MAXCALC], /** Number of forces calculated */
                            AtomForce *atomForce[NOSH_MAXCALC], /** Array of force structures */
                            int i /** Index of force statement to print */
                            );

/**
* @brief  Combine and pretty-print force data
* @ingroup  Frontend
* @author  David Gohara
* @return  1 if successful, 0 otherwise */
VEXTERNC int printApolForce(
                            Vcom *com, /** Communications object */
                            NOsh *nosh, /** Parameters from input file */
                            int nforce[NOSH_MAXCALC], /** Number of forces calculated */
                            AtomForce *atomForce[NOSH_MAXCALC], /** Array of force structures */
                            int i /** Index of force statement to print */
                            );

/**
 * @brief  Wrapper to start MALOC Vio layer
 * @ingroup  Frontend
 * @author  Nathan Baker and Robert Konecny */
VEXTERNC void startVio();

/**
 * @brief  Calculate non-polar energies
 * @ingroup  Frontend
 * @author  David Gohara
 * @return  1 if successful, 0 otherwise */
VEXTERNC int energyAPOL(
                        APOLparm *apolparm, /** APOLparm object */
                        double sasa, /** Solvent accessible surface area */
                        double sav, /** Solvent accessible volume */
                        double atomsasa[], /** Array for SASA per atom **/
                        double atomwcaEnergy[], /** Array for WCA energy per atom **/
                        int numatoms /** Number of atoms (or size of the above arrays) **/
                        );

/**
 * @brief  Calculate non-polar forces
 * @ingroup  Frontend
 * @author  David Gohara
 * @return  1 if successful, 0 otherwise */
VEXTERNC int forceAPOL(
                       Vacc *acc,  /**< Accessiblity object */
                       Vmem *mem,  /**< Memory manager */
                       APOLparm *apolparm,  /**< Apolar calculation parameter
                       object */
                       int *nforce,  /**< Number of atomic forces to calculate
                       statements for */
                       AtomForce **atomForce,  /**< Object for storing atom
                       forces */
                       Valist *alist,  /**< Atom list */
                       Vclist *clist  /**< Cell list for accessibility object */
                       );

/**
 * @brief  Upperlevel routine to the non-polar energy and force routines
 * @ingroup  Frontend
 * @author  David Gohara
 * @return  1 if successful, 0 otherwise */
VEXTERNC int initAPOL(
                      NOsh *nosh,  /**< Input parameter object */
                      Vmem *mem,  /**< Memory manager */
                      Vparam *param,  /**< Atom parameters */
                      APOLparm *apolparm,  /**< Apolar calculation parameters */
                      int *nforce,  /**< Number of force calculations */
                      AtomForce **atomForce,  /**< Atom force storage object */
                      Valist *alist  /**< Atom list */
                      );


#ifdef HAVE_MC
#include "fem/vfetk.h"

/**
 * @brief  Print out FE-specific params loaded from input
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  icalc  Calculation index
 * @param  nosh  Master parameter object
 * @param feparm  FE-specific parameters
 * @param fetk  Array of FE solver objects  */
VEXTERNC void printFEPARM(int icalc, NOsh *nosh, FEMparm *feparm,
  Vfetk *fetk[NOSH_MAXCALC]);

/**
 * @brief  Calculate electrostatic energies from FE solution
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param nosh  Object with parsed input file parameters
 * @param icalc  Index of calculation
 * @param fetk  FE object  array
 * @param nenergy  Set to number of entries in energy arrays
 * @param totEnergy  Set to total energy (in kT)
 * @param qfEnergy  Set to charge-potential energy (in kT)
 * @param qmEnergy  Set to mobile ion energy (in kT)
 * @param dielEnergy  Set to polarization energy (in kT)
 * @bug  "calcenergy 2" does not work
 * @return  1 if successful, 0 otherwise */
VEXTERNC int energyFE(NOsh* nosh, int icalc, Vfetk *fetk[NOSH_MAXCALC],
  int *nenergy, double *totEnergy, double *qfEnergy, double *qmEnergy,
  double *dielEnergy);

/**
 * @brief  Initialize FE solver objects
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @bug  THIS FUNCTION IS HARD-CODED TO SOLVE LRPBE
 * @todo  THIS FUNCTION IS HARD-CODED TO SOLVE LRPBE
 */
VEXTERNC Vrc_Codes initFE(
                    int icalc, /** Index in pb, fetk to initialize (calculation index) */
                    NOsh *nosh,  /** Master parmaeter object */
                    FEMparm *feparm,  /** FE-specific parameters */
                    PBEparm *pbeparm,  /** Generic PBE parameters */
                    Vpbe *pbe[NOSH_MAXCALC],  /** Array of PBE objects */
                    Valist *alist[NOSH_MAXMOL],  /** Array of atom lists */
                    Vfetk *fetk[NOSH_MAXCALC]  /** Array of finite element objects */
);

/**
 * @brief  Kill structures initialized during an FE calculation
 * @ingroup  Frontend
 * @author  Nathan Baker
 */
VEXTERNC void killFE(
                     NOsh *nosh,  /** Object with parsed input file parameters */
                     Vpbe *pbe[NOSH_MAXCALC],  /** Array of Vpbe objects for each calc */
                     Vfetk *fetk[NOSH_MAXCALC],  /** Array of FEtk objects for each calc */
                     Gem *gem[NOSH_MAXMOL]  /** Array of geometry manager objects for each calc */
);

/**
 * @brief  Pre-refine mesh before solve
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  i  Calculation index
 * @param  nosh  Master parameter object
 * @param feparm  FE-specific parameters
 * @param fetk  Array of FE solver objects
 * @return  1 if successful, 0 otherwise */
VEXTERNC int preRefineFE(int i,
                        FEMparm *feparm,
                        Vfetk *fetk[NOSH_MAXCALC]
);

/**
 * @brief  Partition mesh (if applicable)
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  i  Calculation index
 * @param  nosh  Master parameter object
 * @param feparm  FE-specific parameters
 * @param fetk  Array of FE solver objects
 * @return  1 if successful, 0 otherwise */
VEXTERNC int partFE(int i, NOsh *nosh, FEMparm *feparm,
  Vfetk *fetk[NOSH_MAXCALC]);

/**
 * @brief  Solve-estimate-refine
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  i  Calculation index
 * @param feparm  FE-specific parameters
 * @param pbeparm  Generic PBE parameters
 * @param fetk  Array of FE solver objects
 * @return  1 if successful, 0 otherwise */
VEXTERNC int solveFE(int i,
                     PBEparm *pbeparm,
                     FEMparm *feparm,
                     Vfetk *fetk[NOSH_MAXCALC]
);

/**
 * @brief  Estimate error, mark mesh, and refine mesh after solve
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  icalc  Calculation index
 * @param feparm  FE-specific parameters
 * @param fetk  Array of FE solver objects
 * @return  1 if successful, 0 otherwise -- note that a 0 will likely imply
 * that either the max number of vertices have been met or no vertices were
 * marked for refinement.  In either case, this should not be treated as a
 * fatal error.  */
VEXTERNC int postRefineFE(int icalc,
                          FEMparm *feparm,
                          Vfetk *fetk[NOSH_MAXCALC]
);

/**
 * @brief  Write FEM data to files
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  rank  Rank of processor (for parallel runs)
 * @param  nosh  NOsh object
 * @param  pbeparm  PBEparm object
 * @param  fetk  FEtk object (with solution)
 * @return  1 if successful, 0 otherwise */
VEXTERNC int writedataFE(int rank, NOsh *nosh, PBEparm *pbeparm, Vfetk *fetk);

/**
 * @brief  Load the meshes given in NOsh into geometry objects
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @returns  Error code on success/failure */
VEXTERNC Vrc_Codes loadMeshes(
                            NOsh *nosh, /**< NOsh object with input file information */
                            Gem *gm[NOSH_MAXMOL]  /**< List of geometry objects
                            (to be populated) */
                           );

/**
 * @brief  Destroy the loaded meshes
 * @ingroup  Frontend
 * @author  Nathan Baker */
VEXTERNC void killMeshes(
                            NOsh *nosh, /**< NOsh object with input file information */
                            Gem *alist[NOSH_MAXMOL]  /**< Populated list of geometry objects to be destroyed */
                            );
#endif

#endif



VEXTERNC void printMGPARM(MGparm *mgparm, double realCenter[3]);

#ifdef ENABLE_BEM
/**
 * @brief  Initialize an BEM calculation
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @return  1 if succesful, 0 otherwise */
VEXTERNC int initBEM(
                    int icalc,  /**< Index of calculation in pbem/pmbem arrays */
                    NOsh *nosh,  /**< Object with parsed input file parameters */
                    BEMparm *bemparm,  /**< Object with BEM-specific parameters */
                    PBEparm *pbeparm,  /**< Object with generic PBE parameters  */
                    Vpbe *pbe[NOSH_MAXCALC]  /**< Array of Vpbe objects (one for each calc) */
                    );

/**
 * @brief  Kill structures initialized during an BEM calculation
 * @ingroup  Frontend
 * @author  Nathan Baker
 */
VEXTERNC void killBEM(
                     NOsh *nosh,  /** Object with parsed input file parameters */
                     Vpbe *pbe[NOSH_MAXCALC]  /** Array of Vpbe objects for each calc */
);

/**
 * @brief  Solve the PBE with BEM
 * @ingroup  Frontend
 * @author  Nathan Baker, Weihua Geng, Andrew Stevens
 * @param nosh  Object with parsed input file parameters
 * @param pbem  BEM objects for this calculation
 * @param type  Type of BEM calculation
 * @return  1 if successful, 0 otherwise */
VEXTERNC int solveBEM(Valist* molecules[NOSH_MAXMOL],NOsh *nosh, PBEparm *pbeparm, BEMparm *bemparm, BEMparm_CalcType type);

/**
 * @brief  Set MG partitions for calculating observables and performing I/O
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param nosh  Object with parsed input file parameters
 * @param bemparm  BEM parameters from input file
 * @param pbem  BEM object
 * @return  1 if successful, 0 otherwise */
VEXTERNC int setPartBEM(NOsh *nosh, BEMparm *bemparm);

/**
 * @brief  Calculate electrostatic energies from BEM  solution
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param nosh  Object with parsed input file parameters
 * @param icalc  Index of calculation
 * @param pbem  BEM object
 * @param nenergy  Set to number of entries in energy arrays
 * @param totEnergy  Set to total energy (in kT)
 * @param qfEnergy  Set to charge-potential energy (in kT)
 * @param qmEnergy  Set to mobile ion energy (in kT)
 * @param dielEnergy  Set to polarization energy (in kT)
 * @return  1 if successful, 0 otherwise */
VEXTERNC int energyBEM(NOsh* nosh, int icalc,
  int *nenergy, double *totEnergy, double *qfEnergy, double *qmEnergy,
  double *dielEnergy);

/**
 * @brief  Calculate forces from BEM solution
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  mem  Memory management object
 * @param  nosh  Parameters from input file
 * @param  pbeparm  Generic PBE parameters
 * @param  bemparm  BEM-specific parmaeters
 * @param pbem  BEM object
 * @param nforce  Set to number of forces in arrays
 * @param  atomForce  List of atom forces
 * @param  alist  List of atom lists
 * @return  1 if successful, 0 otherwise */
VEXTERNC int forceBEM(NOsh *nosh, PBEparm *pbeparm,  BEMparm *bemparm,
  int *nforce, AtomForce **atomForce, Valist *alist[NOSH_MAXMOL]);

/**
 * @brief  Print out BEM-specific params loaded from input
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  realCenter  Center of mesh for actual calculation
 * @param  bemparm  BEMparm object */
VEXTERNC void printBEMPARM(BEMparm *bemparm);

/**
 * @brief  Write out observables from BEM calculation to file
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  rank  Processor rank (if parallel calculation)
 * @param  nosh  Parameters from input file
 * @param  pbeparm  Generic PBE parameters
 * @param pbem  BEM object
 * @return  1 if successful, 0 otherwise */
VEXTERNC int writedataBEM(int rank, NOsh *nosh, PBEparm *pbeparm);

/**
 * @brief  Write out operator matrix from BEM calculation to file
 * @ingroup  Frontend
 * @author  Nathan Baker
 * @param  rank  Processor rank (if parallel calculation)
 * @param  nosh  Parameters from input file
 * @param  pbeparm  Generic PBE parameters
 * @param pbem  BEM object
 * @return  1 if successful, 0 otherwise */
VEXTERNC int writematBEM(int rank, NOsh *nosh, PBEparm *pbeparm);
#endif

#ifdef ENABLE_GEOFLOW
/**
 * @brief  Solve the PBE with GEOFLOW
 * @ingroup  Frontend
 * @param nosh  Object with parsed input file parameters
 * @param pbem  GEOFLOW objects for this calculation
 * @param type  Type of GEOFLOW calculation
 * @return  1 if successful, 0 otherwise */
VEXTERNC int solveGeometricFlow(
      Valist* molecules[NOSH_MAXMOL],
                                NOsh *nosh,
                                PBEparm *pbeparm,
                                APOLparm *apolparm,
                                GEOFLOWparm *parm
);
#endif

#ifdef ENABLE_PBAM
/**
 * @brief  Solve the LPBE with PBAM
 * @ingroup  Frontend
 * @param nosh  Object with parsed input file parameters
 * @param pbem  PBAM objects for this calculation
 * @param type  Type of PBAM calculation
 * @return  1 if successful, 0 otherwise */
VEXTERNC int solvePBAM(
      Valist* molecules[NOSH_MAXMOL],
                                NOsh *nosh,
                                PBEparm *pbeparm,
                                PBAMparm *parm
);
#endif

#ifdef ENABLE_PBSAM
/**
 * @brief  Solve the LPBE with PBSAM
 * @ingroup  Frontend
 * @param nosh  Object with parsed input file parameters
 * @param pbem  PBAM objects for this calculation
 * @param type  Type of PBAM calculation
 * @return  1 if successful, 0 otherwise */
VEXTERNC int solvePBSAM(
      Valist* molecules[NOSH_MAXMOL],
                                NOsh *nosh,
                                PBEparm *pbeparm,
                                PBAMparm *parm,
                                PBSAMparm *samparm
);
#endif

/**
 * @brief Dump compile-time options to I/O
 * @ingroup Frontend
 */
VEXTERNC void dump_options();