1 //
2 //  PBAM.cpp
3 //  pb_solvers_code
4 //
5 //  Created by Lisa Felberg on 5/24/16.
6 //  Copyright © 2016 Lisa Felberg. All rights reserved.
7 //
8 
9 #include "PBAM.h"
10 
PBAM()11 PBAM::PBAM() : PBAMInput()
12 {
13   poles_ = 5;
14   solveTol_ = 1e-4;
15 
16   vector<string> grid2d = {"tst.2d"};
17   vector<string> gridax = {"x"};
18   vector<double> gridloc = {0.0};
19 
20   // Dynamics
21   vector<string> difftype = {"stat"};
22   vector<vector <double > > diffcon(1, vector<double> (2));
23 
24   vector<string> termtype = {"time"};
25   vector<double> termval = {0.0};
26   vector<vector<int > > termnu = {{0}};
27   vector<string> confil = {""};
28   vector<double> conpad = {0.0};
29   vector<vector<string > > xyzf = {{""}};
30 
31 
32   diffcon[0][0] = 0.0; diffcon[0][1] = 0.0;
33   setp_ = make_shared<Setup>( 300.0, 0.05, 2., 80., 1, "electrostatics", "tst",
34                              false, 100, 0, 15, "tst.map", 1, grid2d,
35                              gridax, gridloc, "tst.dx", 1, false, difftype,
36                              diffcon, termtype, termval, termnu, confil,
37                              conpad, xyzf, "kT");
38   syst_ = make_shared<SystemAM> ();
39   consts_ = make_shared<Constants> ();
40   initialize_coeff_consts();
41 }
42 
43 
PBAM(string infile)44 PBAM::PBAM(string infile)
45 :
46 poles_(5),
47 solveTol_(1e-4)
48 {
49   setp_ = make_shared<Setup>(infile);
50   check_setup();
51 
52   syst_ = make_shared<SystemAM> ();
53   consts_ = make_shared<Constants> (*setp_);
54 
55   check_system();
56   init_write_system();
57 
58   initialize_coeff_consts();
59 }
60 
PBAM(const PBAMInput & pbami,vector<shared_ptr<BaseMolecule>> mls)61 PBAM::PBAM(const PBAMInput& pbami, vector<shared_ptr<BaseMolecule> > mls )
62 :
63 poles_(5),
64 solveTol_(1e-4)
65 {
66   string unt = (pbami.setunits_ == 0) ? "kT" : string(pbami.units_);
67   // Electrostatics
68   int i, j;
69   vector<string> grid2Dname(pbami.grid2Dct_);
70   vector<string> grid2Dax(pbami.grid2Dct_);
71   vector<double> grid2Dloc(pbami.grid2Dct_);
72 
73   for (i=0; i<pbami.grid2Dct_; i++)
74   {
75     grid2Dname[i] = string(pbami.grid2D_[i]);
76     grid2Dax[i] = string(pbami.grid2Dax_[i]);
77     grid2Dloc[i] = pbami.grid2Dloc_[i];
78   }
79 
80   // Dynamics
81   bool termcomb = true;
82   if (string(pbami.termCombine_) == "or")  termcomb = false;
83 
84   vector<string> difftype(pbami.nmol_);
85   vector<vector<double > > diffcon(pbami.nmol_, vector<double> (2));
86   vector<string> termcond(pbami.termct_);
87   vector<double> termval(pbami.termct_);
88   vector<vector<int > > termnu(pbami.termct_, vector<int> (1));
89   vector<double> conpad;
90   vector<string> confil(pbami.contct_);
91   vector<vector <string > > xyzf(pbami.nmol_);
92 
93   if (string(pbami.runType_) == "dynamics")
94   {
95     for (i=0; i<pbami.nmol_; i++)
96     {
97       difftype[i] = string(pbami.moveType_[i]);
98       diffcon[i][0] = pbami.transDiff_[i];
99       diffcon[i][1] = pbami.rotDiff_[i];
100       xyzf[i] = vector<string> (pbami.ntraj_);
101 
102       for (j=0; j<pbami.ntraj_; j++)
103       {
104         xyzf[i][j] = string(pbami.xyzfil_[i][j]);
105       }
106     }
107 
108     for (i=0; i<pbami.termct_; i++)
109     {
110       termcond[i] = string(pbami.termnam_[i]);
111       termval[i] = pbami.termval_[i];
112       termnu[i][0] = pbami.termnu_[i][0];
113 
114       if (termcond[i] == "contact")
115         conpad.push_back(termval[i]);
116     }
117 
118     for (i=0; i<pbami.contct_; i++)
119     {
120       confil[i] = string(pbami.confil_[i]);
121     }
122   }
123 
124   setp_ = make_shared<Setup>(pbami.temp_, pbami.salt_, pbami.idiel_,
125                              pbami.sdiel_, pbami.nmol_, string(pbami.runType_),
126                              string(pbami.runName_), pbami.randOrient_,
127                              pbami.boxLen_, pbami.pbcType_, pbami.gridPts_,
128                              string(pbami.map3D_), pbami.grid2Dct_,
129                              grid2Dname, grid2Dax, grid2Dloc,
130                              string(pbami.dxname_), pbami.ntraj_, termcomb,
131                              difftype, diffcon, termcond, termval, termnu,
132                              confil, conpad, xyzf, unt);
133 
134   check_setup();
135   syst_ = make_shared<SystemAM> (mls, Constants::FORCE_CUTOFF, pbami.boxLen_);
136   consts_ = make_shared<Constants> (*setp_);
137   init_write_system();
138 
139   initialize_coeff_consts();
140 }
141 
142 // Function to check inputs from setup file
check_setup()143 void PBAM::check_setup()
144 {
145   try {
146     setp_->check_inputs();
147   } catch (const BadInputException& ex)
148   {
149     cout << ex.what() << endl;
150     exit(0);
151   }
152   cout << "All inputs okay " << endl;
153 }
154 
155 
156 // Function to check created system
check_system()157 void PBAM::check_system()
158 {
159   try {
160     syst_ = make_shared<SystemAM>(*setp_);
161   } catch(const OverlappingMoleculeException& ex1)
162   {
163     cout << ex1.what() << endl;
164     cout << "Provided system has overlapping MoleculeAMs. ";
165     cout << "Please provide a correct system."<< endl;
166     exit(0);
167   } catch (const NotEnoughCoordsException& ex2)
168   {
169     cout << ex2.what() << endl;
170     exit(0);
171   }
172   cout << "MoleculeAM setup okay " << endl;
173 }
174 
175 
176 // Rotate MoleculeAMs if needed and then write out config to pqr
init_write_system()177 void PBAM::init_write_system()
178 {
179   if (setp_->get_randOrient())
180   {
181     for ( int i = 0; i < syst_->get_n(); i++)
182       syst_->rotate_mol(i, Quat().chooseRandom());
183   }
184 
185   // writing initial configuration out
186   syst_->write_to_pqr( setp_->getRunName() + ".pqr");
187   cout << "Written config" << endl;
188 }
189 
initialize_coeff_consts()190 void PBAM::initialize_coeff_consts()
191 {
192   _bessl_consts_ = make_shared<BesselConstants>(2*poles_);
193   _bessl_calc_ = make_shared<BesselCalc>(2*poles_, _bessl_consts_);
194   _sh_consts_ = make_shared<SHCalcConstants>(2*poles_);
195   _sh_calc_ = make_shared<SHCalc>(2*poles_, _sh_consts_);
196 
197 }
198 
199 
run()200 int PBAM::run()
201 {
202   if ( setp_->getRunType() == "dynamics")
203     run_dynamics();
204   else if ( setp_->getRunType() == "electrostatics")
205     run_electrostatics( );
206   else if ( setp_->getRunType() == "energyforce")
207     run_energyforce( );
208   else if ( setp_->getRunType() == "bodyapprox")
209     run_bodyapprox( );
210   else
211     cout << "Runtype not recognized! See manual for options" << endl;
212 
213   return 0;
214 }
215 
run_apbs()216 PBAMOutput PBAM::run_apbs()
217 {
218   run();
219   PBAMOutput pbamO(syst_->get_n(), force_, nrg_intera_);
220   return pbamO;
221 }
222 
run_dynamics()223 void PBAM::run_dynamics()
224 {
225   int traj, i, j(0);
226   shared_ptr<ASolver> ASolv = make_shared<ASolver> (_bessl_calc_, _sh_calc_,
227 												    syst_, consts_, poles_);
228 
229   vector<shared_ptr<BaseTerminate > >  terms(setp_->get_numterms());
230   for (i = 0; i < setp_->get_numterms(); i++)
231   {
232     string type = setp_->get_termtype(i);
233     string bdtype = type.substr(1,1);
234     double val = setp_->get_termval(i);
235     BoundaryType btype = ( bdtype == "<" ) ? LEQ : GEQ;
236 
237     if ( type == "contact" )
238     {
239       cout << "Contact termination found" << endl;
240       double pad = setp_->get_conpad(j);
241       ContactFile confile (setp_->get_confile(j));
242       auto conterm = make_shared<ContactTerminateAM2>(confile, pad);
243 
244       terms[i] = make_shared<ContactTerminateAM2>(confile, pad);
245       j += 1;  // j is index of contact termconditions
246     } else if (type.substr(0,1) == "x")
247     {
248       cout << type << " termination found for MoleculeAM ";
249       cout << setp_->get_termMolIDX(i)[0] << " at a distance " << val << endl;
250       terms[i] = make_shared<CoordTerminate>( setp_->get_termMolIDX(i)[0],
251                                              X, btype, val);
252     } else if (type.substr(0,1) == "y")
253     {
254       cout << type << " termination found for MoleculeAM ";
255       cout << setp_->get_termMolIDX(i)[0] << " at a distance " << val << endl;
256       terms[i] = make_shared<CoordTerminate>( setp_->get_termMolIDX(i)[0],
257                                              Y, btype, val);
258     } else if (type.substr(0,1) == "z")
259     {
260       cout << type << " termination found for MoleculeAM ";
261       cout << setp_->get_termMolIDX(i)[0] << " at a distance " << val << endl;
262       terms[i] = make_shared<CoordTerminate>( setp_->get_termMolIDX(i)[0],
263                                              Z, btype, val);
264     } else if (type.substr(0,1) == "r")
265     {
266       cout << type << " termination found for MoleculeAM ";
267       cout << setp_->get_termMolIDX(i)[0] << " at a distance " << val << endl;
268       terms[i] = make_shared<CoordTerminate>( setp_->get_termMolIDX(i)[0],
269                                              R, btype, val);
270     } else if (type == "time")
271     {
272       cout << "Time termination found, at AMtime (ps) " << val << endl;
273       terms[i] = make_shared<TimeTerminate>( val);
274     } else cout << "Termination type not recognized!" << endl;
275   }
276 
277   cout << "Done making termination conds " << endl;
278   HowTermCombine com = (setp_->get_andCombine() ? ALL : ONE);
279   auto term_conds = make_shared<CombineTerminate> (terms, com);
280 
281   char buff[100], outb[100];
282   sprintf( outb, "%s.stat", setp_->getRunName().c_str());
283   string statfile = outb;
284 
285   for (traj = 0; traj < setp_->getNTraj(); traj++)
286   {
287     sprintf( buff, "%s_%d.xyz", setp_->getRunName().c_str(), traj);
288     string xyztraj = buff;
289     sprintf( outb, "%s_%d.dat", setp_->getRunName().c_str(), traj);
290     string outfile = outb;
291 
292     string stats = setp_->getRunName();
293     syst_->reset_positions( setp_->get_trajn_xyz(traj));
294     syst_->set_time(0.0);
295     BDRunAM dynamic_run( ASolv, term_conds, outfile);
296     dynamic_run.run(xyztraj, statfile);
297     cout << "Done with trajectory " << traj << endl;
298     if (traj==0)
299       for (i=0; i<syst_->get_n(); i++)
300       {
301         Pt tmp = dynamic_run.get_force_i(i) * consts_->get_conv_factor();
302         force_[i][0] = tmp.x(); force_[i][1] = tmp.y(); force_[i][2] = tmp.z();
303         tmp = dynamic_run.get_torque_i(i) * consts_->get_conv_factor();
304         torque_[i][0] = tmp.x(); torque_[i][1] = tmp.y(); torque_[i][2] = tmp.z();
305         nrg_intera_[i]=dynamic_run.get_energy_i(i)*consts_->get_conv_factor();
306       }
307   }
308 }
309 
run_electrostatics()310 void PBAM::run_electrostatics()
311 {
312   int i;
313   shared_ptr<ASolver> ASolv = make_shared<ASolver> (_bessl_calc_, _sh_calc_,
314                                                     syst_, consts_, poles_);
315   ASolv->solve_A(solveTol_); ASolv->solve_gradA(solveTol_);
316   ElectrostaticAM Estat( ASolv, setp_->getGridPts());
317 
318   if ( setp_->getDXoutName() != "" )
319     Estat.print_dx( setp_->getDXoutName());
320 
321   if ( setp_->get_3dmap_name() != "" )
322     Estat.print_3d_heat( setp_->get_3dmap_name());
323 
324   for ( i = 0; i < setp_->getGridCt(); i++ )
325   {
326     Estat.print_grid(setp_->getGridAx(i), setp_->getGridAxLoc(i),
327                      setp_->getGridOutName(i));
328   }
329 }
330 
331 
run_energyforce()332 void PBAM::run_energyforce()
333 {
334   int i;
335   clock_t t3 = clock();
336   shared_ptr<ASolver> ASolv = make_shared<ASolver> (_bessl_calc_, _sh_calc_,
337                                                     syst_, consts_, poles_);
338   ASolv->solve_A(solveTol_); ASolv->solve_gradA(solveTol_);
339   PhysCalcAM calcEnFoTo( ASolv, setp_->getRunName(), consts_->get_unitsEnum());
340   calcEnFoTo.calc_all();
341   calcEnFoTo.print_all();
342 
343   for (i=0; i<syst_->get_n(); i++)
344   {
345     Pt tmp = calcEnFoTo.get_forcei_conv(i);
346     force_[i][0] = tmp.x(); force_[i][1] = tmp.y(); force_[i][2] = tmp.z();
347     tmp = calcEnFoTo.get_taui_conv(i);
348     torque_[i][0] = tmp.x(); torque_[i][1] = tmp.y(); torque_[i][2] = tmp.z();
349     nrg_intera_[i]  = calcEnFoTo.get_omegai_conv(i);
350   }
351 
352   t3 = clock() - t3;
353   printf ("energyforce calc took me %f seconds.\n",
354           ((float)t3)/CLOCKS_PER_SEC);
355 }
356 
run_bodyapprox()357 void PBAM::run_bodyapprox()
358 {
359   int i;
360   clock_t t3 = clock();
361   shared_ptr<ASolver> ASolv = make_shared<ASolver> (_bessl_calc_, _sh_calc_,
362                                                     syst_, consts_, poles_);
363   ThreeBodyAM threeBodTest( ASolv, consts_->get_unitsEnum(),
364                          setp_->getRunName(), 100.0);
365   threeBodTest.solveNmer(2);
366   threeBodTest.solveNmer(3);
367   t3 = clock() - t3;
368   threeBodTest.calcTBDEnForTor();
369 
370   threeBodTest.printTBDEnForTor(setp_->getRunName(), setp_->getMBDLoc());
371   for (i=0; i<syst_->get_n(); i++)
372   {
373     Pt tmp = threeBodTest.get_forcei_approx(i);
374     force_[i][0] = tmp.x(); force_[i][1] = tmp.y(); force_[i][2] = tmp.z();
375     tmp = threeBodTest.get_torquei_approx(i);
376     torque_[i][0] = tmp.x(); torque_[i][1] = tmp.y(); torque_[i][2] = tmp.z();
377     nrg_intera_[i]  = threeBodTest.get_energyi_approx(i);
378   }
379 
380   t3 = clock() - t3;
381   printf ("manybody approx calc took me %f seconds.\n",
382           ((float)t3)/CLOCKS_PER_SEC);
383 }
384 
385