├── Bin.H ├── CommandLineReader.H ├── CrankNicholsonSolver.H ├── CrankNicholsonSolver1.H ├── CrankNicholsonSolverDirichlet.H ├── DiffusionFusion.H ├── Event.H ├── Examples ├── Simple │ ├── README │ ├── README~ │ ├── comer2_tmax40_skip5_abf_lanGrid0.4.diff │ ├── costEvolution.sh │ ├── doInit.sh │ ├── doInit.sh~ │ ├── energy_lanGrid.shift.dat │ ├── extractData.sh │ ├── extractData.sh~ │ ├── humFine_pen8k_skip20.final.diff │ ├── init.m~ │ ├── init_twoHundred.dat │ ├── init_zero.dat │ ├── output │ │ └── water_thermostat_2ps.traj │ ├── thermostat0.colvars.traj │ ├── thermostat1.colvars.traj │ ├── water_thermostat_2ps.costUpdate.dat │ ├── water_thermostat_2ps.fusion │ ├── water_thermostat_2ps.fusion~ │ └── water_thermostat_2ps.log ├── Smoluchowski │ ├── Data │ │ ├── full_meoh.1.16ps.traj │ │ ├── full_meoh.14.16ps.traj │ │ ├── full_meoh.17.16ps.traj │ │ ├── full_meoh.2.16ps.traj │ │ └── full_meoh.3.16ps.traj │ ├── README │ ├── README~ │ ├── coarse_oneHundred.dat │ ├── coarse_zero.dat │ ├── costEvolution.sh │ ├── costEvolution.sh~ │ ├── doHist.sh │ ├── doHist.sh~ │ ├── doRun.sh │ ├── doRun.sh~ │ ├── fracCoarse_16ps.fusion │ ├── fracCoarse_16ps.fusion~ │ ├── hist.dat │ ├── metroPosterior.tcl │ ├── metroPosterior.tcl~ │ ├── output │ │ └── smolCoarse_16ps.traj │ ├── post_smolCoarse_16ps.diffuse.dat │ ├── smolCoarse_16ps.costUpdate.dat │ ├── smolCoarse_16ps.fusion │ ├── smolCoarse_16ps.fusion~ │ └── smooth_alpha0.7_cen0.75.dat └── TwoDimensional │ ├── Data │ ├── dt8ps_abf_-16_16_popc_etoh.1.traj │ ├── dt8ps_abf_-24_8_popc_etoh.0.traj │ ├── dt8ps_abf_-32_0_popc_etoh.1.traj │ ├── dt8ps_abf_-8_24_popc_etoh.1.traj │ ├── dt8ps_abf_0_32_popc_etoh.1.traj │ ├── dt8ps_abf_0_32a_popc_etoh.1.traj │ └── dt8ps_abf_28_44_popc_etoh.0.traj │ ├── abfX_etoh_6may.fusion │ ├── abfX_etoh_6may.fusion~ │ ├── abfY_etoh_6may.fusion │ ├── abfY_etoh_6may.fusion~ │ ├── init_2d_100000.dx │ ├── init_2d_hundred.dx │ └── init_2d_zero.dx ├── Field.H ├── FieldDesc.H ├── FoxFunc.H ├── HistoryReader.H ├── LICENSE ├── Makefile ├── MetroMonteCarlo.H ├── Piecewise1d.H ├── PiecewiseBicubic.H ├── PiecewiseCubic.H ├── PiecewiseLinear.H ├── PiecewiseZero.H ├── Prior.H ├── README.md ├── RandomGsl.H ├── SmoluchowskiSolver.H ├── SolutionStruct.H ├── TimeFracCrankSolver.H ├── TimeFracCrankSolverDirichlet.H ├── TimeFracCrankSolverFaster.H ├── TrajBdSmoluchowski.H ├── TrajComer.H ├── TrajComer2d.H ├── TrajComer2d2d.H ├── TrajComer2d2d2d.H ├── TrajComerLog.H ├── TrajCostComputer.H ├── TrajCostDesc.H ├── TrajFilter.H ├── TrajFoxFunction.H ├── TrajFracSmolCrank.H ├── TrajFracSmolCrankFaster.H ├── TrajReflect.H ├── TrajReflect2d.H ├── TrajSmolCrank.H ├── TrajSmolCrank1.H ├── TrajSmolCrankBias.H ├── TrialMove.H ├── brownTown2dPassage.C ├── ccgCost.C ├── cubicIntegrate.C ├── diffusionFusion.C ├── doCrank.C ├── doCrankDirichlet.C ├── doFracCrankDirichlet.C ├── doHarmonicDiffusion.C ├── doSmoluchowski.C ├── doSmoluchowskiReflect.C ├── doTimeFrac.C ├── doTimeFracCrank.C ├── dxToArray2d.C ├── dxToGnuplot2d.C ├── insertDataDx2d1.C ├── mapField.C ├── testFox1.C └── useful.H /Bin.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | #ifndef BIN_H 12 | #define BIN_H 13 | 14 | class Bin { 15 | public: 16 | Bin() { 17 | } 18 | 19 | Bin(int n0, double qa, double qb) : n(n0), dx((qb-qa)/n0), x0(qa) { 20 | } 21 | 22 | static int wrapInt(int i, int m) { 23 | int r = i % m; 24 | return r<0 ? r+m : r; 25 | } 26 | 27 | double getCellPosition(int i) const { 28 | return x0 + i*dx; 29 | } 30 | 31 | double getCellCenter(int i) const { 32 | return x0 + (i+0.5)*dx; 33 | } 34 | 35 | int getCellWrap(double x) const { 36 | return wrapInt(int(floor((x - x0)/dx)), n); 37 | } 38 | 39 | int getCell(double x) const { 40 | return int(floor((x - x0)/dx)); 41 | } 42 | 43 | int getCellNearest(double x) const { 44 | return int(floor((x - x0)/dx + 0.5)); 45 | } 46 | 47 | int getCellNearestWrap(double x) const { 48 | return wrapInt(int(floor((x - x0)/dx + 0.5)), n); 49 | } 50 | 51 | public: 52 | int n; 53 | double dx; 54 | double x0; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /CommandLineReader.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Configuration file reader 13 | // Author: Jeff Comer 14 | #ifndef COMMANDLINEREADER_H 15 | #define COMMANDLINEREADER_H 16 | 17 | #include "useful.H" 18 | 19 | class CommandLineReader { 20 | private: 21 | String command; 22 | int paramNum; 23 | String* param; 24 | int optionNum; 25 | String* option; 26 | String* optionValue; 27 | int lineNo; 28 | 29 | public: 30 | // Initialize from the command line. 31 | CommandLineReader(int argc, char** argv) : command(argv[0]), paramNum(0), optionNum(0), lineNo(0) { 32 | // Count the number of parameters and options. 33 | for (int i = 1; i < argc; i++) { 34 | if (argv[i][0] == '-') { 35 | optionNum++; 36 | if (i == argc-1) { 37 | fprintf(stderr, "ERROR CommmandLineReader: Option %s has no value.\n", argv[i]); 38 | exit(-1); 39 | } 40 | i++; 41 | } 42 | else paramNum++; 43 | } 44 | 45 | // Allocate the parameters and options. 46 | param = new String[paramNum]; 47 | option = new String[optionNum]; 48 | optionValue = new String[optionNum]; 49 | 50 | int on = 0; 51 | int pn = 0; 52 | 53 | // Store the options and parameters. 54 | for (int i = 1; i < argc; i++) { 55 | if (argv[i][0] == '-') { 56 | option[on] = &(argv[i][1]); 57 | optionValue[on] = argv[i+1]; 58 | i++; 59 | on++; 60 | } 61 | else { 62 | param[pn] = argv[i]; 63 | pn++; 64 | } 65 | } 66 | } 67 | 68 | CommandLineReader(const char* line, int lineNo0) { 69 | CommandLineReader(String(line), lineNo0); 70 | } 71 | 72 | // Initialize with a string. 73 | CommandLineReader(String line, int lineNo0) : paramNum(0), optionNum(0), lineNo(lineNo0) { 74 | // Extract the tokens. 75 | int tokNum = line.tokenCount(); 76 | String* tok = new String[tokNum]; 77 | line.tokenize(tok); 78 | 79 | // Set the command. 80 | command = tok[0]; 81 | 82 | // Count the number of parameters and options. 83 | for (int i = 1; i < tokNum; i++) { 84 | if (tok[i][0] == '-') { 85 | optionNum++; 86 | if (i == tokNum-1) { 87 | fprintf(stderr,"ERROR CommmandLineReader: Option %s has no value.\n", tok[i].cs()); 88 | exit(-1); 89 | } 90 | i++; 91 | } 92 | else paramNum++; 93 | } 94 | //printf("command %s p %d o %d\n", command.cs(), paramNum, optionNum); 95 | 96 | // Allocate the parameters and options. 97 | param = new String[paramNum]; 98 | option = new String[optionNum]; 99 | optionValue = new String[optionNum]; 100 | 101 | int on = 0; 102 | int pn = 0; 103 | 104 | // Store the options and parameters. 105 | for (int i = 1; i < tokNum; i++) { 106 | if (tok[i][0] == '-') { 107 | option[on] = tok[i].range(1,-1); 108 | optionValue[on] = tok[i+1]; 109 | i++; 110 | on++; 111 | } 112 | else { 113 | param[pn] = tok[i]; 114 | pn++; 115 | } 116 | } 117 | 118 | delete[] tok; 119 | } 120 | 121 | ~CommandLineReader() { 122 | delete[] param; 123 | delete[] option; 124 | delete[] optionValue; 125 | } 126 | 127 | String getCommand() const { 128 | return command; 129 | } 130 | 131 | int getParamNum() const { 132 | return paramNum; 133 | } 134 | 135 | int getOptionNum() const { 136 | return optionNum; 137 | } 138 | 139 | String getParam(int ind) const { 140 | if (ind >= 0 && ind < paramNum) return param[ind]; 141 | return String(); 142 | } 143 | 144 | String getOption(int ind) const { 145 | if (ind >= 0 && ind < optionNum) return option[ind]; 146 | return String(); 147 | } 148 | 149 | String getOptionValue(int ind) const { 150 | if (ind >= 0 && ind < optionNum) return optionValue[ind]; 151 | return String(); 152 | } 153 | 154 | int getLineNumber() const { 155 | return lineNo; 156 | } 157 | 158 | private: 159 | // No default copying. 160 | CommandLineReader(); 161 | CommandLineReader(const CommandLineReader&); 162 | CommandLineReader& operator=(const CommandLineReader&); 163 | }; 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /CrankNicholsonSolverDirichlet.H: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////// 2 | // Interface for a Smoluchowski equation solver 3 | // Author: Jeff Comer 4 | #ifndef CRANKNICHOLSONSOLVER_H 5 | #define CRANKNICHOLSONSOLVER_H 6 | 7 | #include "Piecewise1d.H" 8 | #include 9 | #include 10 | #include 11 | 12 | class CrankNicholsonSolver { 13 | private: 14 | int n; 15 | double dx, x0, x1; 16 | bool periodic; 17 | double timestep; 18 | double beta; 19 | double concLeft; 20 | double concRight; 21 | 22 | public: 23 | CrankNicholsonSolver(const Piecewise1d* refField, double timestep0, double kT, double concLeft0, double concRight0) { 24 | n = refField->length(); 25 | dx = refField->getDr(); 26 | x0 = refField->getR0(); 27 | x1 = refField->getR1(); 28 | periodic = refField->getPeriodic(); 29 | timestep = timestep0; 30 | beta = 1.0/kT; 31 | concLeft = concLeft0; 32 | concRight = concRight0; 33 | } 34 | 35 | int length() const { return n; } 36 | 37 | void init(double* prob, int node) const { 38 | // Zero the initial distribution. 39 | for (int i = 0; i < n; i++) prob[i] = 0.0; 40 | // Add the delta function at the initial point. 41 | prob[node] = 1.0/dx; 42 | } 43 | 44 | double gaussianReflect(double x, double mu, double sigma) const { 45 | double norm = 1.0/(sqrt(2*M_PI)*sigma); 46 | double sigmaSq = sigma*sigma; 47 | return norm*(exp(-0.5*(x-mu)*(x-mu)/sigmaSq) + exp(-0.5*(x-2.0*x0+mu)*(x-2.0*x0+mu)/sigmaSq) + exp(-0.5*(x-2.0*x1+mu)*(x-2.0*x1+mu)/sigmaSq)); 48 | } 49 | 50 | // void init(double* prob, int node) const { 51 | // init(prob,node,dx); 52 | // } 53 | 54 | void init(double* prob, int node, double width) const { 55 | for (int i = 0; i < n; i++) prob[i] = gaussianReflect(dx*i+x0, dx*node+x0, width); 56 | } 57 | 58 | void solve(double* prob, int steps, const Piecewise1d* diffuse, const Piecewise1d* force, const Piecewise1d* bias) const { 59 | // Coefficients contain the diffusion and drift effects. 60 | double ca[n]; 61 | double cb[n]; 62 | double r[n]; 63 | for (int i = 0; i < n; i++) { 64 | // Get the diffusivity and force. 65 | double dif, gradDif; 66 | double frc, gradFrc; 67 | double fb, gradFb; 68 | double x = x0 + i*dx; 69 | diffuse->computeValGrad(x, dif, gradDif); 70 | force->computeValGrad(x, frc, gradFrc); 71 | // dif = diffuse->get(i); 72 | // gradDif = diffuse->getGrad(i); 73 | // frc = force->get(i); 74 | // gradFrc = force->getGrad(i); 75 | 76 | if (bias != NULL) { 77 | bias->computeValGrad(x, fb, gradFb); 78 | frc += fb; 79 | gradFrc += gradFb; 80 | } 81 | 82 | ///////////////////////////////////////////////////////////////// 83 | // We are solving the differential equation for p(x,t) 84 | // p_t = D*p_xx + (D_x - beta*D*F)*p_x - beta*(D*F_x + D_x*F)*p 85 | // Here, subscripts represent partial derivatives. 86 | // D(x): the diffusivity 87 | // F(x,t) = -w_x(x) + fBias(x,t): the total force 88 | // beta: 1/(kT) 89 | // 90 | // We write this equation as 91 | // p_t = ca*p + cb*p_x + D*p_xx 92 | // Below we use r = D*dt/dx^2, consistent with 93 | // Numerical Methods Using Matlab 4th Ed. Mathews and Fink, pp. 561-562 94 | // Calculate the coefficients ca, cb, and r. 95 | ca[i] = -beta*(dif*gradFrc + gradDif*frc)*timestep; 96 | cb[i] = 0.5*(gradDif - beta*dif*frc)/dx*timestep; 97 | r[i] = dif*timestep/(dx*dx); 98 | } 99 | 100 | // Allocate linear system vectors. 101 | // We have a tridiagonal matrix. 102 | // See: https://www.gnu.org/software/gsl/manual/html_node/Tridiagonal-Systems.html 103 | gsl_vector* d = gsl_vector_alloc(n); // Matrix diagonal 104 | gsl_vector* e = gsl_vector_alloc(n-1); // Band to the right of diagonal 105 | gsl_vector* f = gsl_vector_alloc(n-1); // Band to the left of diagonal 106 | gsl_vector* b = gsl_vector_alloc(n); // the right side of Mx = b 107 | gsl_vector* sol = gsl_vector_alloc(n); // the solution "x" 108 | gsl_vector* sol0 = gsl_vector_alloc(n); // a buffer to swap 109 | 110 | // Fill in the matrix. 111 | // Interior nodes using a Crank-Nicholson approach. 112 | // See: Numerical Methods Using Matlab 4th Ed. Mathews and Fink, pp. 561-562 113 | // See: https://www.gnu.org/software/gsl/manual/html_node/Tridiagonal-Systems.html 114 | for (int i = 1; i < n-1; i++) { 115 | gsl_vector_set(d, i, 2.0 + 2.0*r[i] - ca[i]); 116 | gsl_vector_set(f, i-1, cb[i] - r[i]); 117 | gsl_vector_set(e, i, -(cb[i] + r[i])); 118 | } 119 | 120 | // Dirichlet boundary conditions. 121 | gsl_vector_set(d, 0, 1.0); 122 | gsl_vector_set(e, 0, 0.0); 123 | gsl_vector_set(b, 0, concLeft); 124 | // Absorbing at right. 125 | gsl_vector_set(f, n-2, 0.0); 126 | gsl_vector_set(d, n-1, 1.0); 127 | gsl_vector_set(b, n-1, concRight); 128 | 129 | // Intialize the solution vector. 130 | for (int i = 0; i < n; i++) gsl_vector_set(sol, i, prob[i]); 131 | 132 | for (int s = 0; s < steps; s++) { 133 | // Swap the pointers. 134 | gsl_vector* tmp = sol0; 135 | sol0 = sol; 136 | sol = tmp; 137 | 138 | // Fill in the vector b. 139 | // Interior 140 | for (int i = 1; i < n-1; i++) { 141 | gsl_vector_set(b, i, 142 | (2.0 - 2.0*r[i] + ca[i])*gsl_vector_get(sol0, i) 143 | + (r[i] - cb[i])*gsl_vector_get(sol0, i-1) 144 | + (r[i] + cb[i])*gsl_vector_get(sol0, i+1)); 145 | } 146 | 147 | // Solve the system of linear equations. 148 | gsl_linalg_solve_tridiag(d, e, f, b, sol); 149 | } 150 | 151 | // Copy the results into prob. 152 | for (int i = 0; i < n; i++) { 153 | prob[i] = gsl_vector_get(sol, i); 154 | } 155 | 156 | // Deallocate everything. 157 | gsl_vector_free(d); 158 | gsl_vector_free(e); 159 | gsl_vector_free(f); 160 | gsl_vector_free(b); 161 | gsl_vector_free(sol); 162 | gsl_vector_free(sol0); 163 | } 164 | 165 | double conserveProb(double* sol) const { 166 | double sum = 0.0; 167 | for (int i = 0; i < n; i++) sum += sol[i]; 168 | double scale = 1.0/(sum*dx); 169 | //printf("scale %g\n", sum*dx); 170 | for (int i = 0; i < n; i++) sol[i] *= scale; 171 | return scale; 172 | } 173 | 174 | double conserveProb(Piecewise1d& sol) const { 175 | double sum = 0.0; 176 | for (int i = 0; i < sol.length(); i++) sum += sol.get(i); 177 | double scale = 1.0/(sum*sol.getDr()); 178 | //printf("scale %g\n", sum*sol.getDr()); 179 | sol.scale(scale); 180 | return scale; 181 | } 182 | 183 | int positive(double* sol) const { 184 | for (int i = 0; i < n; i++) { 185 | if (sol[i] < -0.5/dx) return i; 186 | } 187 | return -1; 188 | } 189 | 190 | ~CrankNicholsonSolver() { 191 | } 192 | }; 193 | 194 | #endif 195 | -------------------------------------------------------------------------------- /Event.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | #ifndef EVENT_H 14 | #define EVENT_H 15 | 16 | struct Event { 17 | public: 18 | static const int varMax = 8; 19 | double var[varMax]; // variable value 20 | double del[varMax]; // difference in variable 21 | double del0[varMax]; // last difference in variable 22 | int serial; // where does the event lie in the input file? 23 | int bias; // link to bias field 24 | int group; // events can be assigned group numbers 25 | 26 | // Organizational parameters put in an unset state. 27 | Event() : serial(-1), bias(-1), group(0) {} 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Examples/Simple/README: -------------------------------------------------------------------------------- 1 | # You need the Gnu Scientific Library development package installed 2 | (for random numbers) 3 | # Here is the Ubuntu package, which may or may not help you. 4 | # sudo apt-get install gsl-bin libgsl0-dev 5 | 6 | # You may also have to install OpenMP support for g++ (multithreading) 7 | # Here is the Ubuntu package, which may or may not help you 8 | # sudo apt-get install libgomp 9 | 10 | 11 | #### RUN 12 | # Take a look at the diffusionFusion configuration file 13 | water_thermostat_2ps.fusion 14 | # I'll explain these commands below. 15 | # To run it, just do: 16 | ../../diffusionFusion water_thermostat_2ps.fusion 17 | # By default, it will use all of your cores. If you want it to 18 | # use a different number you can specify -nt, as in: 19 | ../../diffusionFusion -nt 2 water_thermostat_2ps.fusion 20 | 21 | #### CHECK 22 | # You should see some diagnostics as it runs and it should dump some 23 | output to "output/". 24 | # When it's done, you can check the PMF with: 25 | xmgrace energy_lanGrid.shift.dat output/water_thermostat_2ps.best.force.pmf & 26 | # The diffusivity should be similar (but not identical) to the Hummer 27 | method result: 28 | xmgrace humFine_pen8k_skip20.final.diff 29 | output/water_thermostat_2ps.best.diffuse & 30 | # If you put the output of diffusionFusion in a file, you can check 31 | out the convergence of the "cost". 32 | # In diffusionFusion, cost = -ln(probability). 33 | ../0_compile/diffusionFusion -nt 4 water_thermostat_2ps.fusion > 34 | water_thermostat_2ps.log & 35 | ./costEvolution.sh water_thermostat_2ps.log 36 | xmgrace water_thermostat_2ps.costUpdate.dat & 37 | 38 | Okay, so what's in the configuration file? The configuration file 39 | consists of commands, which can be given in any order. These commands 40 | have parameters, which are required, and options, which always consist 41 | of "-option val". The order of the options doesn't matter. There is 42 | some explanation of the commands and the options if you run 43 | diffusionFusion with no parameters. 44 | 45 | "output" should be obvious. 46 | 47 | The "dump" command is for diagnostics. "%" means whatever you put for 48 | the "output" command. 49 | 50 | "trajectory" lets you define what's in your trajectory (usually 51 | colvars.traj) files. 52 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 3 53 | Here I say I have a time-like variable that I'm going to call "t", 54 | which appears in the input files in column 0. I define "z" as a 55 | coordinate-like variable that appears in column 1. We get the applied 56 | force (ABF) and put it in a variable called "fz". If you ran in 57 | equilibrium, you can do "-force fz -col .", which gives a variable of 58 | all zeros. The specifications "time" and "force" don't really matter, 59 | but the program really needs to know which columns are coordinates 60 | because these correspond with the fields (force and diffusivity) 61 | below. 62 | 63 | "load" lets you load input files. It takes a lot of options, which 64 | allow you to specify different filters on the data. Here we tell 65 | diffusionFusion that our trajectories have jumps in the coordinate "z" 66 | over the periodic boundaries, for which one period is 67 | [-14.2785,14.2785]. The displacements in z will then be the shortest 68 | displacement consistent with the periodic boundaries (removing jumps). 69 | For the coordinate "t", we rescale the timesteps to be a time in 70 | nanoseconds. 71 | 72 | Now we define our two fields, which are in this case called "diffuse" 73 | and "force". "-step" tells a subsequent "mc" (Monte Carlo) command how 74 | big of steps it should take on this field. You tweak these to get 75 | reasonable acceptance ratios (25-60%). We initialize "diffuse" to a 76 | file containing a bunch of points on the interval [-14.2785,14.2785] 77 | all with the value 200. "force" is initialized to zeros. "-outPmf" 78 | means that although our internal representation is a force, we want to 79 | integrate the force in the output so that we write both the force and 80 | pmf. Two dimensional fields are possible. 81 | 82 | There is also a "loadMany" command that takes the same options but the 83 | input file is a newline separated list of trajectory files. This makes 84 | it easy to load hundreds of files. 85 | 86 | "prior" commands define priors on each field. If you make "-grad" 87 | smaller, it will force the result to be smoother. You are basically 88 | telling the program that you want to penalize gradients substantially 89 | more than -grad. 90 | 91 | "trajCost" defines how the probability of the trajectory is computed. 92 | "ccg" is the method as described in Comer, Chipot and Gonzalez. The 93 | next parameter gives the field that you want to use as the diffusivity 94 | and the one after that is for the force. The order matters for the 95 | parameters. Then you have to tell it which variables correspond to 96 | which parts of the model. Here we calculate the z-diffusivity as a 97 | function of z with the bias force fz exerted along z. Note that if you 98 | have the trajectory data, you could calculate the x-diffusivity as a 99 | function of z quite easily (-pos z -displacement x). "-kt" is k_B T, 100 | so that your PMF comes out in kcal/mol. 101 | 102 | "mc" defines Monte Carlo run. You just list the fields that you want 103 | to apply Monte Carlo to. "-n" gives the number of cycles, while the 104 | other options control the output frequency. A cycle is defined as one 105 | Monte Carlo move attempt per degree of freedom. So how long one cycle 106 | takes depends on the number of points in the fields. "-preview" writes 107 | files with the current state of the fields, which will be named 108 | something like "outputName.3.fieldName" for the third frame. "-output" 109 | says how often it writes all the fields to the 110 | "outputName.3.fieldName". "-update" controls how often the diagnostic 111 | data is written to standard out and also how often the global cost is 112 | updated. 113 | 114 | Aside: What do I mean by "global cost"? When a Monte Carlo move is 115 | made, it only affects the cost of pieces of the trajectory nearby. I 116 | make the program run much faster by only computing the change in the 117 | cost for some pieces of the trajectory affected by the Monte Carlo 118 | move. Due to truncation error the local accumulations of these changes 119 | may drift, so every so often we globally recalculate the cost. Under 120 | normal conditions, the cost with accumulated changes and the globally 121 | recalculated cost differ by something close to the machine precision. 122 | 123 | Sometimes loading the files can be the slow, so you can either filter 124 | them with awk first or write them to an "event file". You do "dump 125 | events eventFile.events" which writes the events (displacements) in 126 | the internal organization of diffusion fusion. The command "loadEvent 127 | eventFile.events" will then load them relatively rapidly, which is 128 | especially good if you're running diffusionFusion on the same 129 | trajectory with different parameters. 130 | -------------------------------------------------------------------------------- /Examples/Simple/README~: -------------------------------------------------------------------------------- 1 | # You need the Gnu Scientific Library development package installed 2 | (for random numbers) 3 | # Here is the Ubuntu package, which may or may not help you. 4 | # sudo apt-get install gsl-bin libgsl0-dev 5 | 6 | # You may also have to install OpenMP support for g++ (multithreading) 7 | # Here is the Ubuntu package, which may or may not help you 8 | # sudo apt-get install libgomp 9 | 10 | #### RUN 11 | cd ../1_water_thermostat 12 | # Take a look at the diffusionFusion configuration file 13 | water_thermostat_2ps.fusion 14 | # I'll explain these commands below. 15 | # To run it, just do: 16 | ../0_compile/diffusionFusion water_thermostat_2ps.fusion 17 | # By default, it will use all of your cores. If you want it to 18 | # use a different number you can specify -nt, as in: 19 | ../0_compile/diffusionFusion -nt 2 water_thermostat_2ps.fusion 20 | 21 | #### CHECK 22 | # You should see some diagnostics as it runs and it should dump some 23 | output to "output/". 24 | # When it's done, you can check the PMF with: 25 | xmgrace energy_lanGrid.shift.dat output/water_thermostat_2ps.best.force.pmf & 26 | # The diffusivity should be similar (but not identical) to the Hummer 27 | method result: 28 | xmgrace humFine_pen8k_skip20.final.diff 29 | output/water_thermostat_2ps.best.diffuse & 30 | # If you put the output of diffusionFusion in a file, you can check 31 | out the convergence of the "cost". 32 | # In diffusionFusion, cost = -ln(probability). 33 | ../0_compile/diffusionFusion -nt 4 water_thermostat_2ps.fusion > 34 | water_thermostat_2ps.log & 35 | ./costEvolution.sh water_thermostat_2ps.log 36 | xmgrace water_thermostat_2ps.costUpdate.dat & 37 | 38 | Okay, so what's in the configuration file? The configuration file 39 | consists of commands, which can be given in any order. These commands 40 | have parameters, which are required, and options, which always consist 41 | of "-option val". The order of the options doesn't matter. There is 42 | some explanation of the commands and the options if you run 43 | diffusionFusion with no parameters. 44 | 45 | "output" should be obvious. 46 | 47 | The "dump" command is for diagnostics. "%" means whatever you put for 48 | the "output" command. 49 | 50 | "trajectory" lets you define what's in your trajectory (usually 51 | colvars.traj) files. 52 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 3 53 | Here I say I have a time-like variable that I'm going to call "t", 54 | which appears in the input files in column 0. I define "z" as a 55 | coordinate-like variable that appears in column 1. We get the applied 56 | force (ABF) and put it in a variable called "fz". If you ran in 57 | equilibrium, you can do "-force fz -col .", which gives a variable of 58 | all zeros. The specifications "time" and "force" don't really matter, 59 | but the program really needs to know which columns are coordinates 60 | because these correspond with the fields (force and diffusivity) 61 | below. 62 | 63 | "load" lets you load input files. It takes a lot of options, which 64 | allow you to specify different filters on the data. Here we tell 65 | diffusionFusion that our trajectories have jumps in the coordinate "z" 66 | over the periodic boundaries, for which one period is 67 | [-14.2785,14.2785]. The displacements in z will then be the shortest 68 | displacement consistent with the periodic boundaries (removing jumps). 69 | For the coordinate "t", we rescale the timesteps to be a time in 70 | nanoseconds. 71 | 72 | Now we define our two fields, which are in this case called "diffuse" 73 | and "force". "-step" tells a subsequent "mc" (Monte Carlo) command how 74 | big of steps it should take on this field. You tweak these to get 75 | reasonable acceptance ratios (25-60%). We initialize "diffuse" to a 76 | file containing a bunch of points on the interval [-14.2785,14.2785] 77 | all with the value 200. "force" is initialized to zeros. "-outPmf" 78 | means that although our internal representation is a force, we want to 79 | integrate the force in the output so that we write both the force and 80 | pmf. Two dimensional fields are possible. 81 | 82 | There is also a "loadMany" command that takes the same options but the 83 | input file is a newline separated list of trajectory files. This makes 84 | it easy to load hundreds of files. 85 | 86 | "prior" commands define priors on each field. If you make "-grad" 87 | smaller, it will force the result to be smoother. You are basically 88 | telling the program that you want to penalize gradients substantially 89 | more than -grad. 90 | 91 | "trajCost" defines how the probability of the trajectory is computed. 92 | "ccg" is the method as described in Comer, Chipot and Gonzalez. The 93 | next parameter gives the field that you want to use as the diffusivity 94 | and the one after that is for the force. The order matters for the 95 | parameters. Then you have to tell it which variables correspond to 96 | which parts of the model. Here we calculate the z-diffusivity as a 97 | function of z with the bias force fz exerted along z. Note that if you 98 | have the trajectory data, you could calculate the x-diffusivity as a 99 | function of z quite easily (-pos z -displacement x). "-kt" is k_B T, 100 | so that your PMF comes out in kcal/mol. 101 | 102 | "mc" defines Monte Carlo run. You just list the fields that you want 103 | to apply Monte Carlo to. "-n" gives the number of cycles, while the 104 | other options control the output frequency. A cycle is defined as one 105 | Monte Carlo move attempt per degree of freedom. So how long one cycle 106 | takes depends on the number of points in the fields. "-preview" writes 107 | files with the current state of the fields, which will be named 108 | something like "outputName.3.fieldName" for the third frame. "-output" 109 | says how often it writes all the fields to the 110 | "outputName.3.fieldName". "-update" controls how often the diagnostic 111 | data is written to standard out and also how often the global cost is 112 | updated. 113 | 114 | Aside: What do I mean by "global cost"? When a Monte Carlo move is 115 | made, it only affects the cost of pieces of the trajectory nearby. I 116 | make the program run much faster by only computing the change in the 117 | cost for some pieces of the trajectory affected by the Monte Carlo 118 | move. Due to truncation error the local accumulations of these changes 119 | may drift, so every so often we globally recalculate the cost. Under 120 | normal conditions, the cost with accumulated changes and the globally 121 | recalculated cost differ by something close to the machine precision. 122 | 123 | Sometimes loading the files can be the slow, so you can either filter 124 | them with awk first or write them to an "event file". You do "dump 125 | events eventFile.events" which writes the events (displacements) in 126 | the internal organization of diffusion fusion. The command "loadEvent 127 | eventFile.events" will then load them relatively rapidly, which is 128 | especially good if you're running diffusionFusion on the same 129 | trajectory with different parameters. 130 | -------------------------------------------------------------------------------- /Examples/Simple/comer2_tmax40_skip5_abf_lanGrid0.4.diff: -------------------------------------------------------------------------------- 1 | -14.26785 489.07927527369 2 | -13.792255 408.77279273002 3 | -13.31666 475.89140770247 4 | -12.841065 472.24688474563 5 | -12.36547 481.04998551085 6 | -11.889875 428.18795537954 7 | -11.41428 470.90136555195 8 | -10.938685 404.9265109956 9 | -10.46309 502.30900430724 10 | -9.987495 427.7438298257 11 | -9.5119 496.97678750243 12 | -9.036305 512.87295393806 13 | -8.56071 451.76799207589 14 | -8.085115 471.1079301674 15 | -7.60952 452.28758712426 16 | -7.133925 446.19410288857 17 | -6.65833 430.47218650163 18 | -6.182735 389.19809369425 19 | -5.70714 387.21083459657 20 | -5.231545 362.97464038314 21 | -4.75595 343.88517098494 22 | -4.280355 326.15143946937 23 | -3.80476 307.72850453482 24 | -3.329165 291.38289996327 25 | -2.85357 266.65799283571 26 | -2.377975 267.73863304216 27 | -1.90238 255.39867726477 28 | -1.426785 265.74344426628 29 | -0.95119 251.07113482175 30 | -0.475595 259.6208130109 31 | 0 259.42754412563 32 | 0.475595 249.48266655461 33 | 0.95119 257.01152800546 34 | 1.426785 244.528786117 35 | 1.90238 253.44604167528 36 | 2.377975 265.82307351939 37 | 2.85357 271.42590914029 38 | 3.329165 285.00052060518 39 | 3.80476 309.45413161808 40 | 4.280355 328.61913837261 41 | 4.75595 351.51175836764 42 | 5.231545 361.47433736012 43 | 5.70714 397.17951881378 44 | 6.182735 384.92961452867 45 | 6.65833 437.37343362866 46 | 7.133925 448.34803795253 47 | 7.60952 460.54830587738 48 | 8.085115 469.67291397707 49 | 8.56071 483.80358913364 50 | 9.036305 387.93342563974 51 | 9.5119 457.31078365584 52 | 9.987495 354.84954357469 53 | 10.46309 433.68170667272 54 | 10.938685 420.871875012 55 | 11.41428 468.09121310932 56 | 11.889875 509.08968222853 57 | 12.36547 469.29015965304 58 | 12.841065 421.64668442241 59 | 13.31666 433.45489608247 60 | 13.792255 459.55396829349 61 | -------------------------------------------------------------------------------- /Examples/Simple/costEvolution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if (( $# != 1 && $# != 2 && $# != 3)); then 4 | echo "Usage: $0 logField [fieldName] [secondName]" 5 | exit 6 | fi 7 | 8 | log=$1 9 | second=$3 10 | bas=${log%.*} 11 | 12 | if (( $# == 1 )); then 13 | field=costUpdate 14 | else 15 | field=$2 16 | fi 17 | 18 | if (( $# == 3 )); then 19 | paste -d " " <(awk 'NF >= 2 && /^cycle / {print $2}' $log) <(awk "/^ $field $second / {print \$3}" $log) > $bas.$field.$second.dat 20 | else 21 | paste -d " " <(awk 'NF >= 2 && /^cycle / {print $2}' $log) <(awk "/^ $field/ {print \$2}" $log) > $bas.$field.dat 22 | fi 23 | -------------------------------------------------------------------------------- /Examples/Simple/doInit.sh: -------------------------------------------------------------------------------- 1 | awk '{print $1,0}' humFine_pen8k_skip20.final.diff> init_zero.dat 2 | awk '{print $1,200}' humFine_pen8k_skip20.final.diff > init_twoHundred.dat 3 | -------------------------------------------------------------------------------- /Examples/Simple/doInit.sh~: -------------------------------------------------------------------------------- 1 | awk '{print $1,0}' comer2_tmax40_skip5_abf_lanGrid0.4.diff > init_zero.dat 2 | awk '{print $1,200}' comer2_tmax40_skip5_abf_lanGrid0.4.diff > init_twoHundred.dat 3 | -------------------------------------------------------------------------------- /Examples/Simple/extractData.sh: -------------------------------------------------------------------------------- 1 | f=../Data/abf_lanGrid0.colvars.traj 2 | #awk '!/^#/ && NF>4 && $1%1000==0 {print $1,$2}' $f > traj.dat 3 | 4 | out=thermostat0.colvars.traj 5 | echo "#step PosZ fs_PosZ fa_PosZ" > $out 6 | awk '!/^#/ && NF>4 && $1%1000==0 && $1<1e7 {print $1,$2,$3,$5}' $f >> $out 7 | out=thermostat1.colvars.traj 8 | echo "#step PosZ fs_PosZ fa_PosZ" > $out 9 | awk '!/^#/ && NF>4 && $1%1000==0 && $1>1e7 {print $1,$2,$3,$5}' $f >> $out 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Examples/Simple/extractData.sh~: -------------------------------------------------------------------------------- 1 | for f in ../Data/abf_lanGrid0.colvars.traj; do 2 | bas=$( basename $f ) 3 | out=thermostat.colvars.traj 4 | 5 | echo "step PosZ fs_PosZ fa_PosZ" > $out 6 | awk '!/^#/ && NF>4 && $1%1000==0 {print $1,$2,$3,$5}' $f >> $out 7 | awk '!/^#/ && NF>4 && $1%1000==0 {print $1,$2}' $f > traj.dat 8 | done 9 | -------------------------------------------------------------------------------- /Examples/Simple/humFine_pen8k_skip20.final.diff: -------------------------------------------------------------------------------- 1 | -14.26785 565.43867490254 2 | -13.792255 556.57210896257 3 | -13.31666 560.32852981472 4 | -12.841065 564.11008637864 5 | -12.36547 566.70608387562 6 | -11.889875 548.42440318316 7 | -11.41428 517.44736450957 8 | -10.938685 511.01299950387 9 | -10.46309 513.01470838953 10 | -9.987495 510.88092781138 11 | -9.5119 517.35452113207 12 | -9.036305 526.58250121167 13 | -8.56071 521.9263200229 14 | -8.085115 509.85184212914 15 | -7.60952 502.15063362382 16 | -7.133925 483.60781912925 17 | -6.65833 454.64614304714 18 | -6.182735 405.19964782521 19 | -5.70714 370.59680285864 20 | -5.231545 329.2274888698 21 | -4.75595 275.37090028869 22 | -4.280355 251.88113632612 23 | -3.80476 218.4731582948 24 | -3.329165 208.55830969987 25 | -2.85357 224.06394454651 26 | -2.377975 231.96426666807 27 | -1.90238 239.67557430733 28 | -1.426785 210.16721352702 29 | -0.95119 188.29761746339 30 | -0.475595 192.60360180633 31 | 0 213.6416468909 32 | 0.475595 209.12528271787 33 | 0.95119 245.42902757647 34 | 1.426785 229.51426145853 35 | 1.90238 231.5611796896 36 | 2.377975 241.89890097128 37 | 2.85357 236.65200329153 38 | 3.329165 245.53536471911 39 | 3.80476 271.37022607028 40 | 4.280355 307.68685089424 41 | 4.75595 313.35275265854 42 | 5.231545 345.77548057074 43 | 5.70714 359.88834294956 44 | 6.182735 382.9544810066 45 | 6.65833 414.28000221029 46 | 7.133925 460.26035651565 47 | 7.60952 495.71022300981 48 | 8.085115 532.43128796807 49 | 8.56071 564.73562434781 50 | 9.036305 575.3963220492 51 | 9.5119 577.17066761805 52 | 9.987495 588.59384566313 53 | 10.46309 591.4634180814 54 | 10.938685 597.34788886504 55 | 11.41428 594.34674075805 56 | 11.889875 587.75410745991 57 | 12.36547 581.69475078583 58 | 12.841065 572.2018572758 59 | 13.31666 567.57301133359 60 | 13.792255 573.51911473554 61 | -------------------------------------------------------------------------------- /Examples/Simple/init.m~: -------------------------------------------------------------------------------- 1 | x = (-12:0.2:12)'; 2 | yz = zeros(size(x)); 3 | y200 = 200.0*ones(size(x)); 4 | 5 | dlmwrite('init_zero.dat',[x yz],' '); 6 | dlmwrite('init_twoHundred.dat',[x y200],' '); 7 | -------------------------------------------------------------------------------- /Examples/Simple/init_twoHundred.dat: -------------------------------------------------------------------------------- 1 | -14.26785 200 2 | -13.792255 200 3 | -13.31666 200 4 | -12.841065 200 5 | -12.36547 200 6 | -11.889875 200 7 | -11.41428 200 8 | -10.938685 200 9 | -10.46309 200 10 | -9.987495 200 11 | -9.5119 200 12 | -9.036305 200 13 | -8.56071 200 14 | -8.085115 200 15 | -7.60952 200 16 | -7.133925 200 17 | -6.65833 200 18 | -6.182735 200 19 | -5.70714 200 20 | -5.231545 200 21 | -4.75595 200 22 | -4.280355 200 23 | -3.80476 200 24 | -3.329165 200 25 | -2.85357 200 26 | -2.377975 200 27 | -1.90238 200 28 | -1.426785 200 29 | -0.95119 200 30 | -0.475595 200 31 | 0 200 32 | 0.475595 200 33 | 0.95119 200 34 | 1.426785 200 35 | 1.90238 200 36 | 2.377975 200 37 | 2.85357 200 38 | 3.329165 200 39 | 3.80476 200 40 | 4.280355 200 41 | 4.75595 200 42 | 5.231545 200 43 | 5.70714 200 44 | 6.182735 200 45 | 6.65833 200 46 | 7.133925 200 47 | 7.60952 200 48 | 8.085115 200 49 | 8.56071 200 50 | 9.036305 200 51 | 9.5119 200 52 | 9.987495 200 53 | 10.46309 200 54 | 10.938685 200 55 | 11.41428 200 56 | 11.889875 200 57 | 12.36547 200 58 | 12.841065 200 59 | 13.31666 200 60 | 13.792255 200 61 | -------------------------------------------------------------------------------- /Examples/Simple/init_zero.dat: -------------------------------------------------------------------------------- 1 | -14.26785 0 2 | -13.792255 0 3 | -13.31666 0 4 | -12.841065 0 5 | -12.36547 0 6 | -11.889875 0 7 | -11.41428 0 8 | -10.938685 0 9 | -10.46309 0 10 | -9.987495 0 11 | -9.5119 0 12 | -9.036305 0 13 | -8.56071 0 14 | -8.085115 0 15 | -7.60952 0 16 | -7.133925 0 17 | -6.65833 0 18 | -6.182735 0 19 | -5.70714 0 20 | -5.231545 0 21 | -4.75595 0 22 | -4.280355 0 23 | -3.80476 0 24 | -3.329165 0 25 | -2.85357 0 26 | -2.377975 0 27 | -1.90238 0 28 | -1.426785 0 29 | -0.95119 0 30 | -0.475595 0 31 | 0 0 32 | 0.475595 0 33 | 0.95119 0 34 | 1.426785 0 35 | 1.90238 0 36 | 2.377975 0 37 | 2.85357 0 38 | 3.329165 0 39 | 3.80476 0 40 | 4.280355 0 41 | 4.75595 0 42 | 5.231545 0 43 | 5.70714 0 44 | 6.182735 0 45 | 6.65833 0 46 | 7.133925 0 47 | 7.60952 0 48 | 8.085115 0 49 | 8.56071 0 50 | 9.036305 0 51 | 9.5119 0 52 | 9.987495 0 53 | 10.46309 0 54 | 10.938685 0 55 | 11.41428 0 56 | 11.889875 0 57 | 12.36547 0 58 | 12.841065 0 59 | 13.31666 0 60 | 13.792255 0 61 | -------------------------------------------------------------------------------- /Examples/Simple/output/water_thermostat_2ps.traj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffcomer/DiffusionFusion/19e23596574992cdb47c8221ebca86da804c202b/Examples/Simple/output/water_thermostat_2ps.traj -------------------------------------------------------------------------------- /Examples/Simple/water_thermostat_2ps.costUpdate.dat: -------------------------------------------------------------------------------- 1 | 20 38855.1700798793 2 | 40 37895.1030481917 3 | 60 37333.6994630457 4 | 80 37083.0543835727 5 | 100 36974.5065310065 6 | 120 36835.5605920516 7 | 140 36781.6610390604 8 | 160 36723.534604372 9 | 180 36673.3460336271 10 | 200 36666.7497080992 11 | 220 36630.5603823139 12 | 240 36640.6694199464 13 | 260 36647.9963622145 14 | 280 36634.6169499907 15 | 300 36611.9108652992 16 | 320 36622.2684080978 17 | 340 36616.5467502733 18 | 360 36617.0503842821 19 | 380 36614.3775703233 20 | 400 36607.976065458 21 | 420 36605.0550054979 22 | 440 36621.7788688019 23 | 460 36621.1263737449 24 | 480 36625.4045546063 25 | 500 36625.3380753314 26 | 520 36616.5121558619 27 | 540 36610.5280060611 28 | 560 36608.4365657855 29 | 580 36618.1426531077 30 | 600 36605.0920312035 31 | 620 36607.4681469082 32 | 640 36610.2863301445 33 | 660 36611.2983093235 34 | 680 36603.7326302889 35 | 700 36618.1847938006 36 | 720 36609.3161950232 37 | 740 36617.9006823061 38 | 760 36611.944266365 39 | 780 36609.4316506988 40 | 800 36614.1531234241 41 | 820 36599.5743228087 42 | 840 36616.0286937567 43 | 860 36621.6630102833 44 | 880 36612.8699872741 45 | 900 36605.7003250186 46 | 920 36624.5028052423 47 | 940 36613.4024105623 48 | 960 36618.0178478586 49 | 980 36622.2687321024 50 | 1000 36603.6756287479 51 | -------------------------------------------------------------------------------- /Examples/Simple/water_thermostat_2ps.fusion: -------------------------------------------------------------------------------- 1 | output output/water_thermostat_2ps 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 3 7 | 8 | load thermostat0.colvars.traj -periodicVar z -periodicMin -14.26785 -periodicMax 14.26785 -scaleVar t -scaleVal 2e-6 -stride 1 9 | load thermostat1.colvars.traj -periodicVar z -periodicMin -14.26785 -periodicMax 14.26785 -scaleVar t -scaleVal 2e-6 -stride 1 10 | 11 | field diffuse cubic -step 3 -f init_twoHundred.dat -minVal 0.1 -periodic 1 12 | field force cubic -step 0.1 -f init_zero.dat -outPmf force -periodic 1 13 | 14 | prior scale diffuse 15 | prior smooth diffuse -grad 20 16 | prior smooth force -grad 10 17 | 18 | trajCost ccg diffuse force -time t -pos z -displacement z -forceBias fz -kt 0.61205887 -leastLocal diffuse 19 | mc diffuse force -n 800 -preview 200 -output 100 -update 20 20 | -------------------------------------------------------------------------------- /Examples/Simple/water_thermostat_2ps.fusion~: -------------------------------------------------------------------------------- 1 | output output/water_thermostat_2ps 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 3 7 | 8 | load thermostat0.colvars.traj -periodicVar z -periodicMin -14.26785 -periodicMax 14.26785 -scaleVar t -scaleVal 2e-6 -stride 1 9 | load thermostat1.colvars.traj -periodicVar z -periodicMin -14.26785 -periodicMax 14.26785 -scaleVar t -scaleVal 2e-6 -stride 1 10 | 11 | field diffuse cubic -step 3 -f init_twoHundred.dat -minVal 0.1 -periodic 1 12 | field force cubic -step 0.1 -f init_zero.dat -outPmf force -periodic 1 13 | 14 | prior scale diffuse 15 | prior smooth diffuse -grad 20 16 | prior smooth force -grad 10 17 | 18 | trajCost ccg diffuse force -time t -pos z -displacement z -forceBias fz -kt 0.61205887 -leastLocal diffuse 19 | mc diffuse force -n 800 -preview 200 -output 100 -update 20 20 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/README: -------------------------------------------------------------------------------- 1 | # Compile diffusionFusion 2 | cd DiffusionFusion 3 | make 4 | # You will need the GNU Scientific Library for this to work. 5 | 6 | cd .. 7 | # Run diffusionFusion 8 | ../../diffusionFusion smolCoarse_16ps.fusion > smolCoarse_16ps.log 9 | # This will take 10-15 minutes to run. 10 | 11 | # While it's running you can check convergence: 12 | bash costEvolution.sh smolCoarse_16ps.log 13 | xmgrace smolCoarse_16ps.costUpdate.dat & 14 | 15 | # You can also see what the D(z) profiles are doing as they are written. 16 | xmgrace smolCoarse_16ps.{0..9}.diffuse & 17 | 18 | # When it's done, you can calculate the posterior distribution (best guess for D(z)). 19 | tclsh metroPosterior.tcl smolCoarse_16ps.traj coarse_oneHundred.dat 1000 1 post_smolCoarse_16ps 20 | xmgrace post_smolCoarse_16ps.diffuse.dat & 21 | 22 | # For fractional diffusivity: 23 | ../../diffusionFusion fracCoarse_16ps.fusion > fracCoarse_16ps.log 24 | # This is much slower. diffusionFusion will automatically use all cores if you have them. "diffusionFusion -nt 2" sets the number of cores to 2. 25 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/README~: -------------------------------------------------------------------------------- 1 | # Compile diffusionFusion 2 | cd DiffusionFusion 3 | make 4 | # You will need the GNU Scientific Library for this to work. 5 | 6 | cd .. 7 | # Run diffusionFusion 8 | DiffusionFusion/diffusionFusion smolCoarse_16ps.fusion > smolCoarse_16ps.log 9 | # This will take 10-15 minutes to run. 10 | 11 | # While it's running you can check convergence: 12 | bash costEvolution.sh smolCoarse_16ps.log 13 | xmgrace smolCoarse_16ps.costUpdate.dat & 14 | 15 | # You can also see what the D(z) profiles are doing as they are written. 16 | xmgrace smolCoarse_16ps.{0..9}.diffuse & 17 | 18 | # When it's done, you can calculate the posterior distribution (best guess for D(z)). 19 | tclsh metroPosterior.tcl smolCoarse_16ps.traj coarse_oneHundred.dat 1000 1 post_smolCoarse_16ps 20 | xmgrace post_smolCoarse_16ps.diffuse.dat & 21 | 22 | # For fractional diffusivity: 23 | DiffusionFusion/diffusionFusion fracCoarse_16ps.fusion > fracCoarse_16ps.log 24 | # This is much slower. diffusionFusion will automatically use all cores if you have them. "diffusionFusion -nt 2" sets the number of cores to 2. 25 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/coarse_oneHundred.dat: -------------------------------------------------------------------------------- 1 | -45 100 2 | -44.5 100 3 | -44 100 4 | -43.5 100 5 | -43 100 6 | -42.5 100 7 | -42 100 8 | -41.5 100 9 | -41 100 10 | -40.5 100 11 | -40 100 12 | -39.5 100 13 | -39 100 14 | -38.5 100 15 | -38 100 16 | -37.5 100 17 | -37 100 18 | -36.5 100 19 | -36 100 20 | -35.5 100 21 | -35 100 22 | -34.5 100 23 | -34 100 24 | -33.5 100 25 | -33 100 26 | -32.5 100 27 | -32 100 28 | -31.5 100 29 | -31 100 30 | -30.5 100 31 | -30 100 32 | -29.5 100 33 | -29 100 34 | -28.5 100 35 | -28 100 36 | -27.5 100 37 | -27 100 38 | -26.5 100 39 | -26 100 40 | -25.5 100 41 | -25 100 42 | -24.5 100 43 | -24 100 44 | -23.5 100 45 | -23 100 46 | -22.5 100 47 | -22 100 48 | -21.5 100 49 | -21 100 50 | -20.5 100 51 | -20 100 52 | -19.5 100 53 | -19 100 54 | -18.5 100 55 | -18 100 56 | -17.5 100 57 | -17 100 58 | -16.5 100 59 | -16 100 60 | -15.5 100 61 | -15 100 62 | -14.5 100 63 | -14 100 64 | -13.5 100 65 | -13 100 66 | -12.5 100 67 | -12 100 68 | -11.5 100 69 | -11 100 70 | -10.5 100 71 | -10 100 72 | -9.5 100 73 | -9 100 74 | -8.5 100 75 | -8 100 76 | -7.5 100 77 | -7 100 78 | -6.5 100 79 | -6 100 80 | -5.5 100 81 | -5 100 82 | -4.5 100 83 | -4 100 84 | -3.5 100 85 | -3 100 86 | -2.5 100 87 | -2 100 88 | -1.5 100 89 | -1 100 90 | -0.5 100 91 | 0 100 92 | 0.5 100 93 | 1 100 94 | 1.5 100 95 | 2 100 96 | 2.5 100 97 | 3 100 98 | 3.5 100 99 | 4 100 100 | 4.5 100 101 | 5 100 102 | 5.5 100 103 | 6 100 104 | 6.5 100 105 | 7 100 106 | 7.5 100 107 | 8 100 108 | 8.5 100 109 | 9 100 110 | 9.5 100 111 | 10 100 112 | 10.5 100 113 | 11 100 114 | 11.5 100 115 | 12 100 116 | 12.5 100 117 | 13 100 118 | 13.5 100 119 | 14 100 120 | 14.5 100 121 | 15 100 122 | 15.5 100 123 | 16 100 124 | 16.5 100 125 | 17 100 126 | 17.5 100 127 | 18 100 128 | 18.5 100 129 | 19 100 130 | 19.5 100 131 | 20 100 132 | 20.5 100 133 | 21 100 134 | 21.5 100 135 | 22 100 136 | 22.5 100 137 | 23 100 138 | 23.5 100 139 | 24 100 140 | 24.5 100 141 | 25 100 142 | 25.5 100 143 | 26 100 144 | 26.5 100 145 | 27 100 146 | 27.5 100 147 | 28 100 148 | 28.5 100 149 | 29 100 150 | 29.5 100 151 | 30 100 152 | 30.5 100 153 | 31 100 154 | 31.5 100 155 | 32 100 156 | 32.5 100 157 | 33 100 158 | 33.5 100 159 | 34 100 160 | 34.5 100 161 | 35 100 162 | 35.5 100 163 | 36 100 164 | 36.5 100 165 | 37 100 166 | 37.5 100 167 | 38 100 168 | 38.5 100 169 | 39 100 170 | 39.5 100 171 | 40 100 172 | 40.5 100 173 | 41 100 174 | 41.5 100 175 | 42 100 176 | 42.5 100 177 | 43 100 178 | 43.5 100 179 | 44 100 180 | 44.5 100 181 | 45 100 182 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/coarse_zero.dat: -------------------------------------------------------------------------------- 1 | -45 0 2 | -44.5 0 3 | -44 0 4 | -43.5 0 5 | -43 0 6 | -42.5 0 7 | -42 0 8 | -41.5 0 9 | -41 0 10 | -40.5 0 11 | -40 0 12 | -39.5 0 13 | -39 0 14 | -38.5 0 15 | -38 0 16 | -37.5 0 17 | -37 0 18 | -36.5 0 19 | -36 0 20 | -35.5 0 21 | -35 0 22 | -34.5 0 23 | -34 0 24 | -33.5 0 25 | -33 0 26 | -32.5 0 27 | -32 0 28 | -31.5 0 29 | -31 0 30 | -30.5 0 31 | -30 0 32 | -29.5 0 33 | -29 0 34 | -28.5 0 35 | -28 0 36 | -27.5 0 37 | -27 0 38 | -26.5 0 39 | -26 0 40 | -25.5 0 41 | -25 0 42 | -24.5 0 43 | -24 0 44 | -23.5 0 45 | -23 0 46 | -22.5 0 47 | -22 0 48 | -21.5 0 49 | -21 0 50 | -20.5 0 51 | -20 0 52 | -19.5 0 53 | -19 0 54 | -18.5 0 55 | -18 0 56 | -17.5 0 57 | -17 0 58 | -16.5 0 59 | -16 0 60 | -15.5 0 61 | -15 0 62 | -14.5 0 63 | -14 0 64 | -13.5 0 65 | -13 0 66 | -12.5 0 67 | -12 0 68 | -11.5 0 69 | -11 0 70 | -10.5 0 71 | -10 0 72 | -9.5 0 73 | -9 0 74 | -8.5 0 75 | -8 0 76 | -7.5 0 77 | -7 0 78 | -6.5 0 79 | -6 0 80 | -5.5 0 81 | -5 0 82 | -4.5 0 83 | -4 0 84 | -3.5 0 85 | -3 0 86 | -2.5 0 87 | -2 0 88 | -1.5 0 89 | -1 0 90 | -0.5 0 91 | 0 0 92 | 0.5 0 93 | 1 0 94 | 1.5 0 95 | 2 0 96 | 2.5 0 97 | 3 0 98 | 3.5 0 99 | 4 0 100 | 4.5 0 101 | 5 0 102 | 5.5 0 103 | 6 0 104 | 6.5 0 105 | 7 0 106 | 7.5 0 107 | 8 0 108 | 8.5 0 109 | 9 0 110 | 9.5 0 111 | 10 0 112 | 10.5 0 113 | 11 0 114 | 11.5 0 115 | 12 0 116 | 12.5 0 117 | 13 0 118 | 13.5 0 119 | 14 0 120 | 14.5 0 121 | 15 0 122 | 15.5 0 123 | 16 0 124 | 16.5 0 125 | 17 0 126 | 17.5 0 127 | 18 0 128 | 18.5 0 129 | 19 0 130 | 19.5 0 131 | 20 0 132 | 20.5 0 133 | 21 0 134 | 21.5 0 135 | 22 0 136 | 22.5 0 137 | 23 0 138 | 23.5 0 139 | 24 0 140 | 24.5 0 141 | 25 0 142 | 25.5 0 143 | 26 0 144 | 26.5 0 145 | 27 0 146 | 27.5 0 147 | 28 0 148 | 28.5 0 149 | 29 0 150 | 29.5 0 151 | 30 0 152 | 30.5 0 153 | 31 0 154 | 31.5 0 155 | 32 0 156 | 32.5 0 157 | 33 0 158 | 33.5 0 159 | 34 0 160 | 34.5 0 161 | 35 0 162 | 35.5 0 163 | 36 0 164 | 36.5 0 165 | 37 0 166 | 37.5 0 167 | 38 0 168 | 38.5 0 169 | 39 0 170 | 39.5 0 171 | 40 0 172 | 40.5 0 173 | 41 0 174 | 41.5 0 175 | 42 0 176 | 42.5 0 177 | 43 0 178 | 43.5 0 179 | 44 0 180 | 44.5 0 181 | 45 0 182 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/costEvolution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #//////////////////////////////////////////////////////////////////// 3 | # Copyright 2014-2016 Jeffrey Comer 4 | # 5 | # This file is part of DiffusionFusion. 6 | # 7 | # DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 8 | # 9 | # DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 12 | #///////////////////////////////////////////////////////////////////// 13 | 14 | if (( $# != 1 && $# != 2 && $# != 3)); then 15 | echo "Usage: $0 logField [fieldName] [secondName]" 16 | exit 17 | fi 18 | 19 | log=$1 20 | second=$3 21 | bas=${log%.*} 22 | 23 | if (( $# == 1 )); then 24 | field=costUpdate 25 | else 26 | field=$2 27 | fi 28 | 29 | if (( $# == 3 )); then 30 | paste -d " " <(awk 'NF >= 2 && /^cycle / {print $2}' $log) <(awk "/^ $field $second / {print \$3}" $log) > $bas.$field.$second.dat 31 | else 32 | paste -d " " <(awk 'NF >= 2 && /^cycle / {print $2}' $log) <(awk "/^ $field/ {print \$2}" $log) > $bas.$field.dat 33 | fi 34 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/costEvolution.sh~: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if (( $# != 1 && $# != 2 && $# != 3)); then 4 | echo "Usage: $0 logField [fieldName] [secondName]" 5 | exit 6 | fi 7 | 8 | log=$1 9 | second=$3 10 | bas=${log%.*} 11 | 12 | if (( $# == 1 )); then 13 | field=costUpdate 14 | else 15 | field=$2 16 | fi 17 | 18 | if (( $# == 3 )); then 19 | paste -d " " <(awk 'NF >= 2 && /^cycle / {print $2}' $log) <(awk "/^ $field $second / {print \$3}" $log) > $bas.$field.$second.dat 20 | else 21 | paste -d " " <(awk 'NF >= 2 && /^cycle / {print $2}' $log) <(awk "/^ $field/ {print \$2}" $log) > $bas.$field.dat 22 | fi 23 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/doHist.sh: -------------------------------------------------------------------------------- 1 | histoDistro Data32/full_meoh.{1,2,3,14,17}.32ps.traj 50 hist.dat 2 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/doHist.sh~: -------------------------------------------------------------------------------- 1 | histoDistro Data32/full_meoh.{1,2,3,14}.32ps.traj 50 hist.dat 2 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/doRun.sh: -------------------------------------------------------------------------------- 1 | #DiffusionFusion/diffusionFusion smolCoarse_16ps.fusion > smolCoarse_16ps.log 2 | bash costEvolution.sh smolCoarse_16ps.log 3 | xmgrace smolCoarse_16ps.costUpdate.dat & 4 | 5 | xmgrace smolCoarse_16ps.{0..9}.diffuse & 6 | 7 | tclsh metroPosterior.tcl smolCoarse_16ps.traj coarse_oneHundred.dat 1000 1 post_smolCoarse_16ps 8 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/doRun.sh~: -------------------------------------------------------------------------------- 1 | DiffusionFusion/diffusionFusion smolCoarse_32ps.fusion 2 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/fracCoarse_16ps.fusion: -------------------------------------------------------------------------------- 1 | output output/fracCoarse_16ps 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col . 7 | 8 | field diffuse cubic -step 2 -f coarse_oneHundred.dat -minVal 0.1 9 | field force cubic -step 0.05 -f coarse_zero.dat 10 | field alpha cubic -step 0.05 -f smooth_alpha0.7_cen0.75.dat -minVal 0.1 -maxVal 1 11 | 12 | prior scale diffuse 13 | prior smooth diffuse -grad 50 14 | 15 | trajCost fracSmolCrank diffuse force alpha -time t -pos z -kt 0.61205887 -timestep 500e-6 -hop 40 16 | mc diffuse -n 2000 -preview 100 -output 10 -update 10 17 | 18 | load Data/full_meoh.1.16ps.traj 19 | load Data/full_meoh.2.16ps.traj 20 | load Data/full_meoh.3.16ps.traj 21 | load Data/full_meoh.14.16ps.traj 22 | load Data/full_meoh.17.16ps.traj 23 | 24 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/fracCoarse_16ps.fusion~: -------------------------------------------------------------------------------- 1 | output fracCoarse_16ps 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col . 7 | 8 | field diffuse cubic -step 2 -f coarse_oneHundred.dat -minVal 0.1 9 | field force cubic -step 0.05 -f coarse_zero.dat 10 | field alpha cubic -step 0.05 -f smooth_alpha0.7_cen0.75.dat -minVal 0.1 -maxVal 1 11 | 12 | prior scale diffuse 13 | prior smooth diffuse -grad 50 14 | 15 | trajCost fracSmolCrank diffuse force alpha -time t -pos z -kt 0.61205887 -timestep 500e-6 -hop 40 16 | mc diffuse -n 2000 -preview 100 -output 10 -update 10 17 | 18 | load Data/full_meoh.1.16ps.traj 19 | load Data/full_meoh.2.16ps.traj 20 | load Data/full_meoh.3.16ps.traj 21 | load Data/full_meoh.14.16ps.traj 22 | load Data/full_meoh.17.16ps.traj 23 | 24 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/hist.dat: -------------------------------------------------------------------------------- 1 | -44.702173332165 75 2 | -42.874873181619 86 3 | -41.047573031072 102 4 | -39.220272880526 91 5 | -37.39297272998 77 6 | -35.565672579433 85 7 | -33.738372428887 65 8 | -31.91107227834 88 9 | -30.083772127794 83 10 | -28.256471977248 84 11 | -26.429171826701 71 12 | -24.601871676155 70 13 | -22.774571525608 88 14 | -20.947271375062 107 15 | -19.119971224516 107 16 | -17.292671073969 134 17 | -15.465370923423 155 18 | -13.638070772876 158 19 | -11.81077062233 152 20 | -9.9834704717835 207 21 | -8.1561703212371 240 22 | -6.3288701706907 216 23 | -4.5015700201443 164 24 | -2.6742698695979 124 25 | -0.8469697190515 164 26 | 0.98033043149491 172 27 | 2.8076305820413 171 28 | 4.6349307325877 151 29 | 6.4622308831341 138 30 | 8.2895310336805 127 31 | 10.116831184227 90 32 | 11.944131334773 57 33 | 13.77143148532 55 34 | 15.598731635866 52 35 | 17.426031786413 39 36 | 19.253331936959 55 37 | 21.080632087505 68 38 | 22.907932238052 64 39 | 24.735232388598 79 40 | 26.562532539145 78 41 | 28.389832689691 79 42 | 30.217132840237 91 43 | 32.044432990784 98 44 | 33.87173314133 113 45 | 35.699033291877 119 46 | 37.526333442423 129 47 | 39.353633592969 139 48 | 41.180933743516 114 49 | 43.008233894062 112 50 | 44.835534044609 82 51 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/metroPosterior.tcl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/tclsh 2 | # Author: Jeff Comer 3 | 4 | #//////////////////////////////////////////////////////////////////// 5 | # Copyright 2014-2016 Jeffrey Comer 6 | # 7 | # This file is part of DiffusionFusion. 8 | # 9 | # DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 10 | # 11 | # DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 14 | #///////////////////////////////////////////////////////////////////// 15 | 16 | if {[llength $argv] != 5} { 17 | puts "Usage: tclsh $argv0 trajFile templateFile firstCycle stride outName" 18 | exit 19 | } 20 | 21 | foreach {trajFile templateFile firstCycle stride outName} $argv { break } 22 | 23 | # Just read a space delimited data file. 24 | proc readData {fileName} { 25 | set in [open $fileName r] 26 | 27 | set r {} 28 | while {[gets $in line] >= 0} { 29 | set line [string trim $line] 30 | if {[string match "#*" $line]} { continue } 31 | if {[string length $line] < 1} { continue } 32 | 33 | set tok [concat $line] 34 | set l {} 35 | foreach t $tok { 36 | lappend l [string trim $t] 37 | } 38 | 39 | lappend r $l 40 | } 41 | 42 | close $in 43 | return $r 44 | } 45 | 46 | # Just read a space delimited data file. 47 | proc readTraj {fileName firstCycle stride arrayVar} { 48 | upvar $arrayVar arr 49 | 50 | set in [open $fileName r] 51 | 52 | set readField {} 53 | set fieldList {} 54 | set cycleCount 0 55 | while {[gets $in line] >= 0} { 56 | if {[string match "#*" $line]} { continue } 57 | if {[string length [string trim $line]] < 1} { continue } 58 | set tok [concat $line] 59 | 60 | # Store the previous field, if we were reading one. 61 | if {[string match "CYCLE*" $line] || [string match "FIELD*" $line]} { 62 | # Ignore cycles before first cycle. 63 | if {[llength $readField] > 0} { 64 | # Store. 65 | lappend arr($readField) $numList 66 | lappend arr(${readField}_cost) $cost 67 | puts "CYCLE $cycle $cost" 68 | puts "field $readField length [llength $numList]" 69 | set readField {} 70 | set numList {} 71 | } 72 | } 73 | 74 | # Read the cycle info. 75 | if {[string match "CYCLE*" $line]} { 76 | set cycle [lindex $tok 1] 77 | set cost [lindex $tok 2] 78 | incr cycleCount 79 | } 80 | 81 | # Skip cycles that are less than firstCycle or don't fit the stride. 82 | if {$cycle >= $firstCycle && $cycleCount % $stride == 0} { 83 | 84 | if {[string match "FIELD*" $line]} { 85 | set readField [lindex $tok 1] 86 | # Keep a list of the fields that have been read. 87 | if {[lsearch $fieldList $readField] < 0} { 88 | puts "Found field $readField" 89 | lappend fieldList $readField 90 | } 91 | } else { 92 | # Store the numeric data. 93 | if {[llength $readField] > 0 && [string is double [lindex $tok 0]]} { 94 | lappend numList [lindex $tok 0] 95 | } 96 | } 97 | } 98 | 99 | } 100 | 101 | # Get the last field that we were reading. 102 | # Store the previous field, if we were reading one. 103 | if {[llength $readField] > 0} { 104 | # Store. 105 | lappend arr($readField) $numList 106 | lappend arr(${readField}_cost) $cost 107 | puts "CYCLE $cycle $cost" 108 | puts "field $readField length [llength $numList]" 109 | set readField {} 110 | set numList {} 111 | } 112 | 113 | 114 | return $fieldList 115 | } 116 | 117 | set templateData [readData $templateFile] 118 | set fieldList [readTraj $trajFile $firstCycle $stride arr] 119 | 120 | set fieldNum [llength $fieldList] 121 | puts "$fieldNum fields in `$trajFile'" 122 | 123 | foreach field $fieldList { 124 | set samples [llength $arr($field)] 125 | puts "$samples samples in field `$field'" 126 | set nodeNum [llength [lindex $arr($field) 0]] 127 | puts "$nodeNum nodes in field `$field'" 128 | if {$nodeNum != [llength $templateData]} { 129 | puts "Warning. `$templateFile' has only [llength $templateData] nodes (should have $nodeNum). Skipping field `$field'." 130 | } 131 | 132 | # Find the minimum cost. 133 | set minCost [lindex $arr(${field}_cost) 0] 134 | foreach cost $arr(${field}_cost) { 135 | if {$cost < $minCost} { set minCost $cost } 136 | } 137 | 138 | # Zero the field sums. 139 | for {set i 0} {$i < $nodeNum} {incr i} { 140 | set sum($i) 0.0 141 | set sumSq($i) 0.0 142 | set count($i) 0 143 | } 144 | 145 | # Calculate the field sums. 146 | foreach frame $arr($field) { 147 | for {set i 0} {$i < $nodeNum} {incr i} { 148 | set val [lindex $frame $i] 149 | set sum($i) [expr {$sum($i) + $val}] 150 | set sumSq($i) [expr {$sumSq($i) + $val*$val}] 151 | incr count($i) 152 | } 153 | } 154 | 155 | # Write the output. 156 | set out [open $outName.$field.dat w] 157 | for {set i 0} {$i < $nodeNum} {incr i} { 158 | set mean [expr {$sum($i)/$count($i)}] 159 | set meanSq [expr {$sumSq($i)/$count($i)}] 160 | set s [expr {$meanSq - $mean*$mean}] 161 | set z [lindex $templateData $i 0] 162 | 163 | if {$s < 0} { 164 | puts "Warning! <${field}^2> - <${field}>^2 < 0, presumably due to numerical error." 165 | puts "We take the standard deviation to be zero." 166 | puts "index $i <${field}^2> $sumSq($i) <${field}>^2 [expr {$mean*$mean}] variance $s" 167 | set std 0.0 168 | } else { 169 | set std [expr {sqrt($s)}] 170 | } 171 | puts $out "$z $mean $std" 172 | } 173 | 174 | close $out 175 | } 176 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/metroPosterior.tcl~: -------------------------------------------------------------------------------- 1 | #!/usr/bin/tclsh 2 | # Author: Jeff Comer 3 | 4 | if {[llength $argv] != 5} { 5 | puts "Usage: tclsh $argv0 trajFile templateFile firstCycle stride outName" 6 | exit 7 | } 8 | 9 | foreach {trajFile templateFile firstCycle stride outName} $argv { break } 10 | 11 | # Just read a space delimited data file. 12 | proc readData {fileName} { 13 | set in [open $fileName r] 14 | 15 | set r {} 16 | while {[gets $in line] >= 0} { 17 | set line [string trim $line] 18 | if {[string match "#*" $line]} { continue } 19 | if {[string length $line] < 1} { continue } 20 | 21 | set tok [concat $line] 22 | set l {} 23 | foreach t $tok { 24 | lappend l [string trim $t] 25 | } 26 | 27 | lappend r $l 28 | } 29 | 30 | close $in 31 | return $r 32 | } 33 | 34 | # Just read a space delimited data file. 35 | proc readTraj {fileName firstCycle stride arrayVar} { 36 | upvar $arrayVar arr 37 | 38 | set in [open $fileName r] 39 | 40 | set readField {} 41 | set fieldList {} 42 | set cycleCount 0 43 | while {[gets $in line] >= 0} { 44 | if {[string match "#*" $line]} { continue } 45 | if {[string length [string trim $line]] < 1} { continue } 46 | set tok [concat $line] 47 | 48 | # Store the previous field, if we were reading one. 49 | if {[string match "CYCLE*" $line] || [string match "FIELD*" $line]} { 50 | # Ignore cycles before first cycle. 51 | if {[llength $readField] > 0} { 52 | # Store. 53 | lappend arr($readField) $numList 54 | lappend arr(${readField}_cost) $cost 55 | puts "CYCLE $cycle $cost" 56 | puts "field $readField length [llength $numList]" 57 | set readField {} 58 | set numList {} 59 | } 60 | } 61 | 62 | # Read the cycle info. 63 | if {[string match "CYCLE*" $line]} { 64 | set cycle [lindex $tok 1] 65 | set cost [lindex $tok 2] 66 | incr cycleCount 67 | } 68 | 69 | # Skip cycles that are less than firstCycle or don't fit the stride. 70 | if {$cycle >= $firstCycle && $cycleCount % $stride == 0} { 71 | 72 | if {[string match "FIELD*" $line]} { 73 | set readField [lindex $tok 1] 74 | # Keep a list of the fields that have been read. 75 | if {[lsearch $fieldList $readField] < 0} { 76 | puts "Found field $readField" 77 | lappend fieldList $readField 78 | } 79 | } else { 80 | # Store the numeric data. 81 | if {[llength $readField] > 0 && [string is double [lindex $tok 0]]} { 82 | lappend numList [lindex $tok 0] 83 | } 84 | } 85 | } 86 | 87 | } 88 | 89 | # Get the last field that we were reading. 90 | # Store the previous field, if we were reading one. 91 | if {[llength $readField] > 0} { 92 | # Store. 93 | lappend arr($readField) $numList 94 | lappend arr(${readField}_cost) $cost 95 | puts "CYCLE $cycle $cost" 96 | puts "field $readField length [llength $numList]" 97 | set readField {} 98 | set numList {} 99 | } 100 | 101 | 102 | return $fieldList 103 | } 104 | 105 | set templateData [readData $templateFile] 106 | set fieldList [readTraj $trajFile $firstCycle $stride arr] 107 | 108 | set fieldNum [llength $fieldList] 109 | puts "$fieldNum fields in `$trajFile'" 110 | 111 | foreach field $fieldList { 112 | set samples [llength $arr($field)] 113 | puts "$samples samples in field `$field'" 114 | set nodeNum [llength [lindex $arr($field) 0]] 115 | puts "$nodeNum nodes in field `$field'" 116 | if {$nodeNum != [llength $templateData]} { 117 | puts "Warning. `$templateFile' has only [llength $templateData] nodes (should have $nodeNum). Skipping field `$field'." 118 | } 119 | 120 | # Find the minimum cost. 121 | set minCost [lindex $arr(${field}_cost) 0] 122 | foreach cost $arr(${field}_cost) { 123 | if {$cost < $minCost} { set minCost $cost } 124 | } 125 | 126 | # Zero the field sums. 127 | for {set i 0} {$i < $nodeNum} {incr i} { 128 | set sum($i) 0.0 129 | set sumSq($i) 0.0 130 | set count($i) 0 131 | } 132 | 133 | # Calculate the field sums. 134 | foreach frame $arr($field) { 135 | for {set i 0} {$i < $nodeNum} {incr i} { 136 | set val [lindex $frame $i] 137 | set sum($i) [expr {$sum($i) + $val}] 138 | set sumSq($i) [expr {$sumSq($i) + $val*$val}] 139 | incr count($i) 140 | } 141 | } 142 | 143 | # Write the output. 144 | set out [open $outName.$field.dat w] 145 | for {set i 0} {$i < $nodeNum} {incr i} { 146 | set mean [expr {$sum($i)/$count($i)}] 147 | set meanSq [expr {$sumSq($i)/$count($i)}] 148 | set s [expr {$meanSq - $mean*$mean}] 149 | set z [lindex $templateData $i 0] 150 | 151 | if {$s < 0} { 152 | puts "Warning! <${field}^2> - <${field}>^2 < 0, presumably due to numerical error." 153 | puts "We take the standard deviation to be zero." 154 | puts "index $i <${field}^2> $sumSq($i) <${field}>^2 [expr {$mean*$mean}] variance $s" 155 | set std 0.0 156 | } else { 157 | set std [expr {sqrt($s)}] 158 | } 159 | puts $out "$z $mean $std" 160 | } 161 | 162 | close $out 163 | } 164 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/output/smolCoarse_16ps.traj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffcomer/DiffusionFusion/19e23596574992cdb47c8221ebca86da804c202b/Examples/Smoluchowski/output/smolCoarse_16ps.traj -------------------------------------------------------------------------------- /Examples/Smoluchowski/smolCoarse_16ps.costUpdate.dat: -------------------------------------------------------------------------------- 1 | 10 28541.5156464443 2 | 20 27941.6339704672 3 | 30 27555.4047372159 4 | 40 27305.4940193938 5 | 50 27114.3065899713 6 | 60 26940.6924263721 7 | 70 26837.0898801291 8 | 80 26771.5339640807 9 | 90 26688.837819802 10 | 100 26641.7515289373 11 | 110 26586.3086255644 12 | 120 26540.3392523695 13 | 130 26518.4760547459 14 | 140 26485.3854852927 15 | 150 26457.691399188 16 | 160 26455.4020501866 17 | 170 26433.142365819 18 | 180 26419.6600404187 19 | 190 26406.3635810467 20 | 200 26397.574390634 21 | 210 26390.7243406318 22 | 220 26397.907966127 23 | 230 26383.253664756 24 | 240 26378.8030956956 25 | 250 26390.0096457195 26 | 260 26379.2676044549 27 | 270 26374.2529754243 28 | 280 26371.8498098391 29 | 290 26372.913811467 30 | 300 26370.9125913723 31 | 310 26360.0973967342 32 | 320 26354.6648169963 33 | 330 26373.987564631 34 | 340 26375.4822169475 35 | 350 26352.2062427536 36 | 360 26358.9829746205 37 | 370 26368.8300387754 38 | 380 26357.9263661872 39 | 390 26353.4847397406 40 | 400 26359.6882689564 41 | 410 26355.6990893307 42 | 420 26332.860057635 43 | 430 26348.1377231585 44 | 440 26331.3100292416 45 | 450 26343.2714566044 46 | 460 26357.3511959326 47 | 470 26351.4554767873 48 | 480 26355.3144243724 49 | 490 26348.0494945302 50 | 500 26354.4532052211 51 | 510 26333.6286454359 52 | 520 26345.6142475307 53 | 530 26338.0519613391 54 | 540 26330.1981226318 55 | 550 26328.264741123 56 | 560 26322.9448154803 57 | 570 26323.9537409685 58 | 580 26325.424754586 59 | 590 26331.3291547997 60 | 600 26317.139392791 61 | 610 26325.7599729155 62 | 620 26320.3126859305 63 | 630 26333.6208497485 64 | 640 26330.4562578154 65 | 650 26325.7886616681 66 | 660 26323.7582313853 67 | 670 26327.3822016399 68 | 680 26334.8169272472 69 | 690 26331.5478338241 70 | 700 26332.0984824765 71 | 710 26341.5517407785 72 | 720 26326.832566468 73 | 730 26333.2926551176 74 | 740 26328.4273676382 75 | 750 26315.8656589877 76 | 760 26312.3799461354 77 | 770 26309.9380671522 78 | 780 26318.1307649186 79 | 790 26320.6266269456 80 | 800 26314.4071421583 81 | 810 26327.9491771039 82 | 820 26326.181828209 83 | 830 26315.3554644362 84 | 840 26318.1273745383 85 | 850 26322.6029864309 86 | 860 26320.5918040522 87 | 870 26338.0780955154 88 | 880 26330.7484678958 89 | 890 26313.9344304236 90 | 900 26321.9829973141 91 | 910 26311.4724702835 92 | 920 26325.5915376055 93 | 930 26324.2227792968 94 | 940 26329.3287213354 95 | 950 26324.5854384568 96 | 960 26338.5437699328 97 | 970 26339.27581753 98 | 980 26330.6681521862 99 | 990 26319.6685927027 100 | 1000 26310.1295267466 101 | 1010 26308.8446076061 102 | 1020 26318.5051185704 103 | 1030 26320.1668453278 104 | 1040 26311.136942099 105 | 1050 26319.3160896352 106 | 1060 26312.6019356848 107 | 1070 26327.3414268513 108 | 1080 26322.321975035 109 | 1090 26315.7682546366 110 | 1100 26316.1915185818 111 | 1110 26327.6546295211 112 | 1120 26313.703981814 113 | 1130 26325.9236866008 114 | 1140 26319.4611691038 115 | 1150 26327.3821160475 116 | 1160 26318.3113896905 117 | 1170 26320.6340905713 118 | 1180 26322.8417768877 119 | 1190 26318.3049841141 120 | 1200 26327.888414969 121 | 1210 26327.1334884867 122 | 1220 26332.86361577 123 | 1230 26322.7464156098 124 | 1240 26325.4487613963 125 | 1250 26328.4631275966 126 | 1260 26313.5462692411 127 | 1270 26316.4336410183 128 | 1280 26335.6796497452 129 | 1290 26318.270247201 130 | 1300 26311.2377269109 131 | 1310 26308.7086454913 132 | 1320 26314.9546233099 133 | 1330 26311.9823962405 134 | 1340 26326.7619229041 135 | 1350 26328.6285805026 136 | 1360 26323.7530062534 137 | 1370 26337.5395212793 138 | 1380 26324.0779800252 139 | 1390 26317.7182490495 140 | 1400 26322.649018157 141 | 1410 26327.7328431388 142 | 1420 26309.7836744724 143 | 1430 26327.1626690758 144 | 1440 26321.2363770501 145 | 1450 26311.9479149474 146 | 1460 26318.7100512596 147 | 1470 26315.9946764343 148 | 1480 26324.5291012213 149 | 1490 26321.5756922543 150 | 1500 26316.4000896382 151 | 1510 26324.80742778 152 | 1520 26320.231979245 153 | 1530 26325.0346706632 154 | 1540 26320.5789946191 155 | 1550 26323.6911182809 156 | 1560 26330.0768461114 157 | 1570 26328.3277401412 158 | 1580 26319.7040541146 159 | 1590 26322.6512858089 160 | 1600 26318.0436112985 161 | 1610 26316.9774030704 162 | 1620 26322.1705145679 163 | 1630 26316.1373785933 164 | 1640 26315.2424786006 165 | 1650 26317.3418481177 166 | 1660 26334.858162102 167 | 1670 26327.6903917157 168 | 1680 26327.7535260584 169 | 1690 26325.4087883015 170 | 1700 26332.4175129915 171 | 1710 26327.2769024474 172 | 1720 26318.2389379231 173 | 1730 26309.3927155058 174 | 1740 26310.5454858418 175 | 1750 26311.1778958943 176 | 1760 26322.3014852462 177 | 1770 26316.740617899 178 | 1780 26316.1526206502 179 | 1790 26322.2469568176 180 | 1800 26325.3161753986 181 | 1810 26331.1075609311 182 | 1820 26321.9345017661 183 | 1830 26315.2824283802 184 | 1840 26319.8796657432 185 | 1850 26330.2838587284 186 | 1860 26324.4293858515 187 | 1870 26322.5704985923 188 | 1880 26320.7422303856 189 | 1890 26326.2485786112 190 | 1900 26329.3888548689 191 | 1910 26309.2690196231 192 | 1920 26318.2239948349 193 | 1930 26324.7424006619 194 | 1940 26324.8569001246 195 | 1950 26337.7267056041 196 | 1960 26322.1521105769 197 | 1970 26318.1031973287 198 | 1980 26320.9113557811 199 | 1990 26305.8268480502 200 | 2000 26324.4531347726 201 | 2010 26324.2495514743 202 | 2020 26315.41782544 203 | 2030 26320.1034425753 204 | 2040 26330.9380201203 205 | 2050 26321.403101859 206 | 2060 26327.5984558629 207 | 2070 26321.7809858289 208 | 2080 26315.7506153816 209 | 2090 26308.4063650056 210 | 2100 26314.7775106045 211 | 2110 26310.2632117529 212 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/smolCoarse_16ps.fusion: -------------------------------------------------------------------------------- 1 | output output/smolCoarse_16ps 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col . 7 | 8 | field diffuse cubic -step 2 -f coarse_oneHundred.dat -minVal 0.1 9 | field force cubic -step 0.05 -f coarse_zero.dat 10 | 11 | prior scale diffuse 12 | prior smooth diffuse -grad 50 13 | 14 | trajCost smolCrank diffuse force -time t -pos z -kt 0.61205887 -timestep 500e-6 -hop 40 15 | mc diffuse -n 2000 -preview 100 -output 10 -update 10 16 | 17 | load Data/full_meoh.1.16ps.traj 18 | load Data/full_meoh.2.16ps.traj 19 | load Data/full_meoh.3.16ps.traj 20 | load Data/full_meoh.14.16ps.traj 21 | load Data/full_meoh.17.16ps.traj 22 | 23 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/smolCoarse_16ps.fusion~: -------------------------------------------------------------------------------- 1 | output smolCoarse_16ps 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col . 7 | 8 | field diffuse cubic -step 2 -f coarse_oneHundred.dat -minVal 0.1 9 | field force cubic -step 0.05 -f coarse_zero.dat 10 | 11 | prior scale diffuse 12 | prior smooth diffuse -grad 50 13 | 14 | trajCost smolCrank diffuse force -time t -pos z -kt 0.61205887 -timestep 500e-6 -hop 40 15 | mc diffuse -n 2000 -preview 100 -output 10 -update 10 16 | 17 | load Data/full_meoh.1.16ps.traj 18 | load Data/full_meoh.2.16ps.traj 19 | load Data/full_meoh.3.16ps.traj 20 | load Data/full_meoh.14.16ps.traj 21 | load Data/full_meoh.17.16ps.traj 22 | 23 | -------------------------------------------------------------------------------- /Examples/Smoluchowski/smooth_alpha0.7_cen0.75.dat: -------------------------------------------------------------------------------- 1 | -45.0 1.0 2 | -44.5 1.0 3 | -44.0 1.0 4 | -43.5 1.0 5 | -43.0 1.0 6 | -42.5 1.0 7 | -42.0 1.0 8 | -41.5 1.0 9 | -41.0 1.0 10 | -40.5 1.0 11 | -40.0 1.0 12 | -39.5 1.0 13 | -39.0 1.0 14 | -38.5 1.0 15 | -38.0 1.0 16 | -37.5 1.0 17 | -37.0 1.0 18 | -36.5 1.0 19 | -36.0 1.0 20 | -35.5 1.0 21 | -35.0 1.0 22 | -34.5 1.0 23 | -34.0 1.0 24 | -33.5 1.0 25 | -33.0 1.0 26 | -32.5 1.0 27 | -32.0 1.0 28 | -31.5 1.0 29 | -31.0 1.0 30 | -30.5 1.0 31 | -30.0 1.0 32 | -29.5 1.0 33 | -29.0 1.0 34 | -28.5 0.9999866165971681 35 | -28.0 0.9999385881674004 36 | -27.5 0.999784355885654 37 | -27.0 0.9993411584521338 38 | -26.5 0.9982015274700421 39 | -26.0 0.9955792640557348 40 | -25.5 0.9901800139984767 41 | -25.0 0.9802320174722164 42 | -24.5 0.9638305439985203 43 | -24.0 0.9396327840288842 44 | -23.5 0.9076870758207107 45 | -23.0 0.8699476807826175 46 | -22.5 0.8300523192173824 47 | -22.0 0.7923129241792892 48 | -21.5 0.7603672159711158 49 | -21.0 0.7361694560014796 50 | -20.5 0.7197679825277834 51 | -20.0 0.7098199860015232 52 | -19.5 0.704420735944265 53 | -19.0 0.7017984725299576 54 | -18.5 0.700658841547866 55 | -18.0 0.7002156441143459 56 | -17.5 0.7000614118325993 57 | -17.0 0.7000133834028317 58 | -16.5 0.7 59 | -16.0 0.7 60 | -15.5 0.7 61 | -15.0 0.7 62 | -14.5 0.7 63 | -14.0 0.7 64 | -13.5 0.7 65 | -13.0 0.7 66 | -12.5 0.7 67 | -12.0 0.7 68 | -11.5 0.7 69 | -11.0 0.7 70 | -10.5 0.7000022305671385 71 | -10.0 0.700010235305433 72 | -9.5 0.7000359406857242 73 | -9.0 0.7001098069246443 74 | -8.5 0.7002997454216596 75 | -8.0 0.7007367893240443 76 | -7.5 0.7016366643335873 77 | -7.0 0.7032946637546306 78 | -6.5 0.7060282426669133 79 | -6.0 0.7100612026618527 80 | -5.5 0.715385487363215 81 | -5.0 0.7216753865362304 82 | -4.5 0.7283246134637696 83 | -4.0 0.7346145126367852 84 | -3.5 0.7399387973381475 85 | -3.0 0.7439717573330868 86 | -2.5 0.7467053362453695 87 | -2.0 0.7483633356664129 88 | -1.5 0.7492632106759559 89 | -1.0 0.7496980240112019 90 | -0.5 0.7498799577699226 91 | 0.0 0.7499281186285515 92 | 0.5 0.7498799577699224 93 | 1.0 0.7496980240112018 94 | 1.5 0.7492632106759558 95 | 2.0 0.7483633356664128 96 | 2.5 0.7467053362453694 97 | 3.0 0.7439717573330866 98 | 3.5 0.7399387973381473 99 | 4.0 0.734614512636785 100 | 4.5 0.7283246134637695 101 | 5.0 0.7216753865362303 102 | 5.5 0.7153854873632147 103 | 6.0 0.7100612026618525 104 | 6.5 0.7060282426669132 105 | 7.0 0.7032946637546305 106 | 7.5 0.7016366643335872 107 | 8.0 0.7007367893240442 108 | 8.5 0.7002997454216595 109 | 9.0 0.7001098069246442 110 | 9.5 0.7000359406857242 111 | 10.0 0.700010235305433 112 | 10.5 0.7000022305671385 113 | 11.0 0.7 114 | 11.5 0.7 115 | 12.0 0.7 116 | 12.5 0.7 117 | 13.0 0.7 118 | 13.5 0.7 119 | 14.0 0.7 120 | 14.5 0.7 121 | 15.0 0.7 122 | 15.5 0.7 123 | 16.0 0.7 124 | 16.5 0.7 125 | 17.0 0.7000133834028318 126 | 17.5 0.7000614118325994 127 | 18.0 0.700215644114346 128 | 18.5 0.7006588415478662 129 | 19.0 0.7017984725299578 130 | 19.5 0.7044207359442651 131 | 20.0 0.7098199860015232 132 | 20.5 0.7197679825277834 133 | 21.0 0.7361694560014796 134 | 21.5 0.7603672159711158 135 | 22.0 0.7923129241792891 136 | 22.5 0.8300523192173823 137 | 23.0 0.8699476807826174 138 | 23.5 0.9076870758207107 139 | 24.0 0.9396327840288841 140 | 24.5 0.9638305439985202 141 | 25.0 0.9802320174722163 142 | 25.5 0.9901800139984765 143 | 26.0 0.9955792640557348 144 | 26.5 0.9982015274700423 145 | 27.0 0.9993411584521339 146 | 27.5 0.9997843558856541 147 | 28.0 0.9999385881674006 148 | 28.5 0.9999866165971681 149 | 29.0 1.0 150 | 29.5 1.0 151 | 30.0 1.0 152 | 30.5 1.0 153 | 31.0 1.0 154 | 31.5 1.0 155 | 32.0 1.0 156 | 32.5 1.0 157 | 33.0 1.0 158 | 33.5 1.0 159 | 34.0 1.0 160 | 34.5 1.0 161 | 35.0 1.0 162 | 35.5 1.0 163 | 36.0 1.0 164 | 36.5 1.0 165 | 37.0 1.0 166 | 37.5 1.0 167 | 38.0 1.0 168 | 38.5 1.0 169 | 39.0 1.0 170 | 39.5 1.0 171 | 40.0 1.0 172 | 40.5 1.0 173 | 41.0 1.0 174 | 41.5 1.0 175 | 42.0 1.0 176 | 42.5 1.0 177 | 43.0 1.0 178 | 43.5 1.0 179 | 44.0 1.0 180 | 44.5 1.0 181 | 45.0 1.0 182 | -------------------------------------------------------------------------------- /Examples/TwoDimensional/abfX_etoh_6may.fusion: -------------------------------------------------------------------------------- 1 | output output/abfX_etoh_6may 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 2 -coor theta -col 3 -force ft -col 4 7 | 8 | load Data/dt8ps_abf_-16_16_popc_etoh.1.traj -minVar z -minVal -14 -maxVar z -maxVal 14 -stride 1 9 | load Data/dt8ps_abf_-24_8_popc_etoh.0.traj -minVar z -minVal -22 -maxVar z -maxVal 6 -stride 1 10 | load Data/dt8ps_abf_-32_0_popc_etoh.1.traj -minVar z -minVal -30 -maxVar z -maxVal -2 -stride 1 11 | load Data/dt8ps_abf_-8_24_popc_etoh.1.traj -minVar z -minVal -6 -maxVar z -maxVal 22 -stride 1 12 | load Data/dt8ps_abf_0_32_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 13 | load Data/dt8ps_abf_0_32a_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 14 | load Data/dt8ps_abf_28_44_popc_etoh.0.traj -minVar z -minVal 30 -maxVar z -maxVal 42 -stride 1 15 | 16 | field diffuseX bicubic -step 10 -minVal 10 -f init_2d_hundred.dx 17 | field forceX bicubic -step 0.1 -f init_2d_zero.dx 18 | 19 | prior scale diffuseX 20 | prior smooth diffuseX -grad 50 21 | prior smooth forceX -grad 5 22 | 23 | trajCost ccg2d diffuseX forceX -time t -posX z -posY theta -displacement z -forceBias fz -kt 0.6120596 -dim 0 24 | mc diffuseX forceX -n 500 -preview 100 -output 20 -update 20 25 | -------------------------------------------------------------------------------- /Examples/TwoDimensional/abfX_etoh_6may.fusion~: -------------------------------------------------------------------------------- 1 | output output/abfX_etoh_6may 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 2 -coor theta -col 3 -force ft -col 4 7 | 8 | load Data/dt8ps_abf_-16_16_popc_etoh.1.traj -minVar z -minVal -14 -maxVar z -maxVal 14 -stride 1 9 | load Data/dt8ps_abf_-16_16_popc_etoh.2.traj -minVar z -minVal -14 -maxVar z -maxVal 14 -stride 1 10 | load Data/dt8ps_abf_-24_8_popc_etoh.0.traj -minVar z -minVal -22 -maxVar z -maxVal 6 -stride 1 11 | load Data/dt8ps_abf_-32_0_popc_etoh.1.traj -minVar z -minVal -30 -maxVar z -maxVal -2 -stride 1 12 | load Data/dt8ps_abf_-32_0a_popc_etoh.1.traj -minVar z -minVal -30 -maxVar z -maxVal -2 -stride 1 13 | load Data/dt8ps_abf_-8_24_popc_etoh.1.traj -minVar z -minVal -6 -maxVar z -maxVal 22 -stride 1 14 | load Data/dt8ps_abf_0_32_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 15 | load Data/dt8ps_abf_0_32a_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 16 | load Data/dt8ps_abf_0_32a_popc_etoh.2.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 17 | load Data/dt8ps_abf_28_44_popc_etoh.0.traj -minVar z -minVal 30 -maxVar z -maxVal 42 -stride 1 18 | 19 | field diffuseX bicubic -step 10 -minVal 10 -f init_2d_hundred.dx 20 | field forceX bicubic -step 0.1 -f init_2d_zero.dx 21 | 22 | prior scale diffuseX 23 | prior smooth diffuseX -grad 50 24 | prior smooth forceX -grad 5 25 | 26 | trajCost ccg2d diffuseX forceX -time t -posX z -posY theta -displacement z -forceBias fz -kt 0.6120596 -dim 0 27 | mc diffuseX forceX -n 500 -preview 100 -output 20 -update 20 28 | -------------------------------------------------------------------------------- /Examples/TwoDimensional/abfY_etoh_6may.fusion: -------------------------------------------------------------------------------- 1 | output output/abfY_etoh_6may 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 2 -coor theta -col 3 -force ft -col 4 7 | 8 | load Data/dt8ps_abf_-16_16_popc_etoh.1.traj -minVar z -minVal -14 -maxVar z -maxVal 14 -stride 1 9 | load Data/dt8ps_abf_-24_8_popc_etoh.0.traj -minVar z -minVal -22 -maxVar z -maxVal 6 -stride 1 10 | load Data/dt8ps_abf_-32_0_popc_etoh.1.traj -minVar z -minVal -30 -maxVar z -maxVal -2 -stride 1 11 | load Data/dt8ps_abf_-8_24_popc_etoh.1.traj -minVar z -minVal -6 -maxVar z -maxVal 22 -stride 1 12 | load Data/dt8ps_abf_0_32_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 13 | load Data/dt8ps_abf_0_32a_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 14 | load Data/dt8ps_abf_28_44_popc_etoh.0.traj -minVar z -minVal 30 -maxVar z -maxVal 42 -stride 1 15 | 16 | field diffuseY bicubic -step 500 -minVal 10 -f init_2d_100000.dx 17 | field forceY bicubic -step 0.1 -f init_2d_zero.dx 18 | 19 | prior scale diffuseY 20 | prior smooth diffuseY -grad 10000 21 | prior smooth forceY -grad 5 22 | 23 | trajCost ccg2d diffuseY forceY -time t -posX z -posY theta -displacement theta -forceBias ft -kt 0.6120596 -dim 1 24 | mc diffuseY forceY -n 500 -preview 100 -output 20 -update 20 25 | -------------------------------------------------------------------------------- /Examples/TwoDimensional/abfY_etoh_6may.fusion~: -------------------------------------------------------------------------------- 1 | output output/abfY_etoh_6may 2 | dump distro %.gt.hist 3 | dump best %.best 4 | #dump events %.events 5 | 6 | trajectory -time t -col 0 -coor z -col 1 -force fz -col 2 -coor theta -col 3 -force ft -col 4 7 | 8 | load Data/dt8ps_abf_-16_16_popc_etoh.1.traj -minVar z -minVal -14 -maxVar z -maxVal 14 -stride 1 9 | load Data/dt8ps_abf_-16_16_popc_etoh.2.traj -minVar z -minVal -14 -maxVar z -maxVal 14 -stride 1 10 | load Data/dt8ps_abf_-24_8_popc_etoh.0.traj -minVar z -minVal -22 -maxVar z -maxVal 6 -stride 1 11 | load Data/dt8ps_abf_-32_0_popc_etoh.1.traj -minVar z -minVal -30 -maxVar z -maxVal -2 -stride 1 12 | load Data/dt8ps_abf_-32_0a_popc_etoh.1.traj -minVar z -minVal -30 -maxVar z -maxVal -2 -stride 1 13 | load Data/dt8ps_abf_-8_24_popc_etoh.1.traj -minVar z -minVal -6 -maxVar z -maxVal 22 -stride 1 14 | load Data/dt8ps_abf_0_32_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 15 | load Data/dt8ps_abf_0_32a_popc_etoh.1.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 16 | load Data/dt8ps_abf_0_32a_popc_etoh.2.traj -minVar z -minVal 2 -maxVar z -maxVal 30 -stride 1 17 | load Data/dt8ps_abf_28_44_popc_etoh.0.traj -minVar z -minVal 30 -maxVar z -maxVal 42 -stride 1 18 | 19 | field diffuseY bicubic -step 500 -minVal 10 -f init_2d_100000.dx 20 | field forceY bicubic -step 0.1 -f init_2d_zero.dx 21 | 22 | prior scale diffuseY 23 | prior smooth diffuseY -grad 10000 24 | prior smooth forceY -grad 5 25 | 26 | trajCost ccg2d diffuseY forceY -time t -posX z -posY theta -displacement theta -forceBias ft -kt 0.6120596 -dim 1 27 | mc diffuseY forceY -n 500 -preview 100 -output 20 -update 20 28 | -------------------------------------------------------------------------------- /Field.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Interface for a field of real numbers. 13 | // Author: Jeff Comer 14 | #ifndef FIELD_H 15 | #define FIELD_H 16 | 17 | #include "useful.H" 18 | 19 | class Field { 20 | public: 21 | static const int maxDim = 4; 22 | protected: 23 | double* v0; 24 | double* err; 25 | int n; 26 | bool periodic; 27 | 28 | public: 29 | Field(const double* in, int n0, bool periodic) : n(n0), periodic(false) { 30 | v0 = new double[n]; 31 | err = new double[n]; 32 | for (int i = 0; i < n; i++) { 33 | err[i] = 0.0; 34 | v0[i] = in[i]; 35 | } 36 | } 37 | 38 | Field(int n0, bool periodic0) : n(n0), periodic(periodic0) { 39 | v0 = new double[n]; 40 | err = new double[n]; 41 | for (int i = 0; i < n; i++) { 42 | err[i] = 0.0; 43 | v0[i] = 0.0; 44 | } 45 | } 46 | 47 | Field(const Field& tab) { 48 | n = tab.n; 49 | v0 = new double[n]; 50 | err = new double[n]; 51 | for (int i = 0; i < n; i++) { 52 | v0[i] = tab.v0[i]; 53 | err[i] = tab.err[i]; 54 | } 55 | periodic = tab.periodic; 56 | } 57 | 58 | virtual Field& operator=(const Field& tab) { 59 | // Resize the arrays if necessary. 60 | if (n != tab.n) { 61 | delete[] v0; 62 | delete[] err; 63 | n = tab.n; 64 | v0 = new double[n]; 65 | err = new double[n]; 66 | } 67 | 68 | // Copy the values. 69 | for (int i = 0; i < n; i++) { 70 | v0[i] = tab.v0[i]; 71 | err[i] = tab.err[i]; 72 | } 73 | periodic = tab.periodic; 74 | 75 | return (*this); 76 | } 77 | 78 | virtual ~Field() { 79 | delete[] v0; 80 | delete[] err; 81 | } 82 | 83 | // How many elements? 84 | int length() const { return n; } 85 | // The periodicity. 86 | bool getPeriodic() const { return periodic; } 87 | void setPeriodic(bool b) { periodic = b; } 88 | // Get and set elements. 89 | bool validIndex(int j) const { return (j >= 0) && (j < n); } 90 | inline double get(int j) const { 91 | //if (j < 0 || j >= n) return 0.0; 92 | return v0[j]; 93 | } 94 | double operator[](int j) const { 95 | if (j < 0 || j >= n) return 0.0; 96 | return v0[j]; 97 | } 98 | 99 | // Just dump the numeric data. 100 | void dump(FILE* out) const { 101 | for (int i = 0; i < n; i++) fprintf(out, "%.14g\n", v0[i]); 102 | } 103 | 104 | // Write the error data. 105 | bool writeErr(const String& fileName) const { 106 | // Open the file. 107 | FILE* out = fopen(fileName.cs(),"w"); 108 | if (out == NULL) { 109 | printf("Couldn't open file `%s' for writing.\n",fileName.cs()); 110 | return false; 111 | } 112 | 113 | for (int i = 0; i < n; i++) fprintf(out, "%.14g\n", err[i]); 114 | fclose(out); 115 | return true; 116 | } 117 | 118 | void save(double* saveData) const { 119 | for (int i = 0; i < n; i++) saveData[i] = v0[i]; 120 | } 121 | 122 | // Allow changes to the error. 123 | double getErr(int j) const { 124 | if (j < 0 || j >= n) return 0.0; 125 | return err[j]; 126 | } 127 | bool setErr(int j, double ev) { 128 | if (j < 0 || j >= n) return false; 129 | err[j] = ev; 130 | return true; 131 | } 132 | 133 | // Basic wrapping if periodic. 134 | inline int wrapInt(int i, int ni) const { 135 | if (periodic) { 136 | int r = i % ni; 137 | return r<0 ? r+ni : r; 138 | } else { 139 | // Aperiodic. 140 | if (i < 0) return 0; 141 | if (i >= ni) return ni-1; 142 | return i; 143 | } 144 | } 145 | 146 | // Static wrapping of floating point values, whether the field is periodic or not. 147 | inline static double wrapReal(double x, double l) { 148 | int image = int(floor(x/l)); 149 | return x - image*l; 150 | } 151 | inline static double wrapReal(double x, double x0, double x1) { 152 | double l = x1-x0; 153 | int image = int(floor((x-x0)/l)); 154 | return x - image*l; 155 | } 156 | inline static double wrapRealDiff(double x, double l) { 157 | int image = int(floor(x/l)); 158 | x -= image*l; 159 | if (x >= 0.5*l) x -= l; 160 | return x; 161 | } 162 | inline static double wrapRealDiff(double x, double x0, double x1) { 163 | double l = x1-x0; 164 | int image = int(floor(x/l)); 165 | x -= image*l; 166 | if (x >= 0.5*l) x -= l; 167 | return x; 168 | } 169 | 170 | // Functions that the derived classes must implement. 171 | // Neighbors must include node j. 172 | virtual IndexList neighbors(int j) const = 0; 173 | // Include the minimal neighbors. 174 | virtual IndexList neighborsMinimal(int j) const = 0; 175 | // Set the value of a node. Is virtual so that interpolants can be updated. 176 | virtual bool set(int j, double v) = 0; 177 | // Read the field from its file. 178 | virtual void read(const String& fileName, bool periodic0) = 0; 179 | // Write the field to a file. 180 | virtual bool write(const String& fileName) const = 0; 181 | // The nearest node to the position (which may be a vector of any size). 182 | virtual int nearestNode(const double* pos) const = 0; 183 | // The nearest node with all coordinates less than those of pos. 184 | virtual int getNode(const double* pos) const = 0; 185 | // Get the position of a node along dimension dim. 186 | virtual double nodePos(int j, int dim) const = 0; 187 | // The integral of the field. 188 | virtual bool writeIntegral(const String& fileName, double scale) const = 0; 189 | // The log of the field. 190 | virtual bool writeLog(const String& fileName, double scale) const = 0; 191 | 192 | // For the smoothness prior. 193 | virtual int prevIndex(int j, int dir) const = 0; 194 | virtual int nextIndex(int j, int dir) const = 0; 195 | virtual double spacing(int j, int dir) const = 0; 196 | // For the known prior. 197 | // Map the values of 'srcVal' to the nodes of this. 198 | // You'll probably have to delete the field returned by this function. 199 | virtual Field* map(const Field* srcVal) const = 0; 200 | // Check that 'srcVal' is at least as big as '*this'. 201 | virtual bool spannedBy(const Field* srcVal) const = 0; 202 | 203 | // How many dimensions does the field have? 204 | virtual int dimensions() const = 0; 205 | 206 | protected: 207 | // Let PiecewiseCubic take care of all of the initialization. 208 | Field() {} 209 | }; 210 | 211 | #endif 212 | -------------------------------------------------------------------------------- /FieldDesc.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // A struct with all public members for holding a descriptor of a Field. 12 | // Author: Jeff Comer 13 | #ifndef FIELDDESC_H 14 | #define FIELDDESC_H 15 | 16 | struct FieldDesc { 17 | int id; 18 | String name, type, trajVar; 19 | bool hasMin, hasMax; 20 | double minVal, maxVal; 21 | double step; 22 | double initVal; 23 | int n; 24 | String file; 25 | bool periodic; 26 | IndexList varList; 27 | IndexList priorList; 28 | bool outLog; 29 | bool outInt; 30 | String errFile; 31 | String fixedFile; 32 | IndexList freeNodeList; 33 | bool global; 34 | 35 | String toString() const { 36 | String s; 37 | char cs[STRLEN]; 38 | // Usual stuff. 39 | snprintf(cs, STRLEN, "field %s type %s step %g", name.cs(), type.cs(), step); 40 | s.add(cs); 41 | // Optional stuff. 42 | if (global) { 43 | snprintf(cs, STRLEN, " global"); 44 | s.add(cs); 45 | } 46 | if (file.length() != 0) { 47 | snprintf(cs, STRLEN, " file %s", file.cs()); 48 | s.add(cs); 49 | } else { 50 | snprintf(cs, STRLEN, " n %d initVal %g", n, initVal); 51 | s.add(cs); 52 | } 53 | if (errFile.length() != 0) { 54 | snprintf(cs, STRLEN, " errFile %s", errFile.cs()); 55 | s.add(cs); 56 | } 57 | if (hasMin) { 58 | snprintf(cs, STRLEN, " minVal %g", minVal); 59 | s.add(cs); 60 | } 61 | if (hasMax) { 62 | snprintf(cs, STRLEN, " maxVal %g", maxVal); 63 | s.add(cs); 64 | } 65 | if (fixedFile.length() != 0) { 66 | snprintf(cs, STRLEN, " fixedFile %s", fixedFile.cs()); 67 | s.add(cs); 68 | } 69 | if (periodic) { 70 | snprintf(cs, STRLEN, " periodic"); 71 | s.add(cs); 72 | } 73 | for (int v = 0; v < varList.length(); v++) { 74 | snprintf(cs, STRLEN, " var %d", varList.get(v)); 75 | s.add(cs); 76 | } 77 | return s; 78 | } 79 | }; 80 | #endif 81 | -------------------------------------------------------------------------------- /FoxFunc.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | ///////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | // Implementation of Equation 46 of 14 | // Metzler and Klafter, Physics Reports 339 (2000) 1-77 15 | // Using Gnu Scientific Library 16 | 17 | #ifndef FOXFUNC_H 18 | #define FOXFUNC_H 19 | 20 | #include 21 | #include 22 | 23 | class FoxFunc { 24 | private: 25 | int iterations; 26 | 27 | public: 28 | // 40 iterations keeps errors below 5e-8 for alpha=0.1, larger alpha better 29 | FoxFunc() : iterations(40) {} 30 | FoxFunc(int iterations0) : iterations(iterations0) {} 31 | 32 | double stretchedGaussian(double x, double alpha, double sqrtKt, double fx) { 33 | double a1 = 1.0-alpha; 34 | double a2 = 2.0-alpha; 35 | double e = -0.5*a2*pow(0.5*alpha,alpha/a2)*pow(fx,1.0/(1.0-0.5*alpha)); 36 | double res = sqrt(1.0/a2)*pow(2.0/alpha, a1/a2)*pow(fx,-a1/a2)*exp(e); 37 | return 0.5*res/(sqrtKt*sqrt(M_PI)); 38 | } 39 | 40 | double w (double x, double alpha, double kAlpha, double t) { 41 | double sqrtKt = sqrt(kAlpha*pow(t,alpha)); 42 | double fx = fabs(x)/sqrtKt; 43 | 44 | // Check if we can do the asymptotic instead. 45 | // The 20.0-12.66*alpha is based on empirical calculations 46 | // for getting a difference <1e-9 between the series and the asymptotic 47 | // difference of <1e-6, 12.108-7.55*alpha 48 | if (fx > 12.12 - 7.55*alpha) return stretchedGaussian(x, alpha, sqrtKt, fx); 49 | 50 | double sum = gsl_sf_gammainv(1.0-0.5*alpha); 51 | int n = 1; 52 | double nFac = 1.0; 53 | double fxToN = 1.0; 54 | while (n < iterations) { 55 | nFac *= -n; 56 | fxToN *= fx; 57 | double term = gsl_sf_gammainv(1.0-0.5*alpha*(n+1))*fxToN/nFac; 58 | sum += term; 59 | n++; 60 | } 61 | 62 | return 0.5*sum/sqrtKt; 63 | } 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ROOT=diffusionFusion 2 | # DON'T USE -ffast-math, it seems to keep things from converging 3 | 4 | default: gnu 5 | 6 | gnu: 7 | g++ -O3 -Wall -march=native -mfpmath=sse -DGSL_RANGE_CHECK_OFF -DHAVE_INLINE $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 8 | 9 | linux: 10 | g++ -O3 -Wall -mfpmath=sse -DHAVE_INLINE $(ROOT).C -o $(ROOT)_LINUX -lm -lgsl -lgslcblas -fopenmp 11 | 12 | linuxdebug: 13 | g++ -ggdb -DFUSION_DEBUG -Wall -DHAVE_INLINE $(ROOT).C -o $(ROOT)_LINUX -lm -lgsl -lgslcblas -fopenmp 14 | 15 | stable: 16 | g++ -O1 -Wall $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 17 | 18 | debug: 19 | g++ -ggdb -Wall $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 20 | 21 | fdebug: 22 | g++ -DFUSION_DEBUG -Wall $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 23 | 24 | clean: 25 | rm $(ROOT) 26 | 27 | mac: 28 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 29 | 30 | macquick: 31 | g++ -I/opt/local/include -L/opt/local/lib -O0 -Wall $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 32 | 33 | mac_debug: 34 | macdebug: 35 | g++ -I/opt/local/include -L/opt/local/lib -DFUSION_DEBUG -ggdb -Wall $(ROOT).C -o $(ROOT) -lm -lgsl -lgslcblas -fopenmp 36 | 37 | debug_no_gsl: 38 | g++ -DNO_GSL -ggdb -Wall $(ROOT).C -o $(ROOT) -lm -fopenmp 39 | 40 | dx: 41 | g++ -O2 -Wall dxToArray2d.C -o dxToArray2d 42 | integ: 43 | g++ -O2 -Wall cubicIntegrate.C -o cubicIntegrate 44 | insert: 45 | g++ -O2 -Wall insertDataDx2d1.C -o insertDataDx2d 46 | map: 47 | g++ -O2 -Wall mapField.C -o mapField 48 | 49 | ccgCost: 50 | g++ -O2 -Wall ccgCost.C -o ccgCost 51 | gnuplot: 52 | g++ -O2 -Wall dxToGnuplot2d.C -o dxToGnuplot2d 53 | brown: 54 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE brownTown2d.C -o brownTown2d -lm -lgsl -lgslcblas 55 | passage: 56 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE brownTown2dPassage.C -o brownTown2dPassage -lm -lgsl -lgslcblas 57 | 58 | fox: 59 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE testFox.C -o testFox -lm -lgsl -lgslcblas 60 | 61 | fox1: 62 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE testFox1.C -o testFox1 -lm -lgsl -lgslcblas 63 | 64 | smol: 65 | g++ -O2 -Wall doSmoluchowskiReflect.C -o doSmoluchowskiReflect -lm -fopenmp 66 | smoldebug: 67 | g++ -ggdb doSmoluchowskiReflect.C -o doSmoluchowskiReflect -lm -fopenmp 68 | 69 | crank: 70 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF doCrank.C -o doCrank -lm -lgsl -lgslcblas -fopenmp 71 | crankdir: 72 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF doCrankDirichlet.C -o doCrankDirichlet -lm -lgsl -lgslcblas -fopenmp 73 | gamma: 74 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF gammaTest.C -o gammaTest -lm -lgsl -lgslcblas 75 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF gTest.C -o gTest -lm -lgsl -lgslcblas 76 | timefrac: 77 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF doTimeFracCrank.C -o doTimeFracCrank -lm -lgsl -lgslcblas -fopenmp 78 | timefrac_debug: 79 | g++ -ggdb -Wall doTimeFracCrank.C -o doTimeFracCrank -lm -lgsl -lgslcblas -fopenmp 80 | fracdir: 81 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF doFracCrankDirichlet.C -o doFracCrankDirichlet -lm -lgsl -lgslcblas -fopenmp 82 | fracdir_debug: 83 | g++ -ggdb -Wall doFracCrankDirichlet.C -o doFracCrankDirichlet -lm -lgsl -lgslcblas -fopenmp 84 | 85 | fracfick: 86 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF doFracCrankDirichletFick.C -o doFracCrankDirichletFick -lm -lgsl -lgslcblas -fopenmp 87 | 88 | crankfick: 89 | g++ -I/opt/local/include -L/opt/local/lib -O3 -Wall -DHAVE_INLINE -DGSL_RANGE_CHECK_OFF doCrankDirichletFick.C -o doCrankDirichletFick -lm -lgsl -lgslcblas -fopenmp 90 | 91 | -------------------------------------------------------------------------------- /MetroMonteCarlo.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Metropolis Monte Carlo over fields 13 | // Author: Jeff Comer 14 | #ifndef METROMONTECARLO_H 15 | #define METROMONTECARLO_H 16 | 17 | #include "Field.H" 18 | #include "FieldDesc.H" 19 | #include "TrialMove.H" 20 | #include "RandomGsl.H" 21 | 22 | class MetroMonteCarlo { 23 | private: 24 | // For the fields on which we are applying Monte Carlo. 25 | int fieldNum; 26 | // An array of pointers to the fields on which we are applying Monte Carlo. 27 | Field** mcField; 28 | // An array of pointers to their descriptors. 29 | const FieldDesc** mcFieldDesc; 30 | // Random number generator 31 | Random* rando; 32 | IndexList mcLocalFields; 33 | 34 | // Trial move variables. 35 | int trialField, trialNode; 36 | double trialLastVal, trialVal; 37 | 38 | int stepsPerCycle; 39 | 40 | public: 41 | MetroMonteCarlo(Field** ppf, const FieldDesc* pfd, const IndexList& selection, Random* rando0) { 42 | fieldNum = selection.length(); 43 | if (fieldNum == 0) { 44 | fprintf(stderr, "ERROR MetroMonteCarlo must act on at least one field.\n"); 45 | exit(-1); 46 | } 47 | 48 | // Choose the selection of fields to undergo Monte Carlo. 49 | mcField = new Field*[fieldNum]; 50 | mcFieldDesc = new const FieldDesc*[fieldNum]; 51 | for (int i = 0; i < fieldNum; i++) { 52 | mcField[i] = ppf[selection.get(i)]; 53 | mcFieldDesc[i] = &pfd[selection.get(i)]; 54 | if (!mcFieldDesc[i]->global) mcLocalFields.add(i); 55 | } 56 | 57 | // Get the number of steps per cycle (equal to the number of field nodes). 58 | stepsPerCycle = 0; 59 | for (int f = 0; f < fieldNum; f++) stepsPerCycle += mcField[f]->length(); 60 | 61 | rando = rando0; 62 | } 63 | 64 | ~MetroMonteCarlo() { 65 | // Note that the field objects themselves are owned by DiffusionFusion. 66 | // We just deallocate our arrays of pointers to them. 67 | delete[] mcField; 68 | delete[] mcFieldDesc; 69 | // rando is owned by the caller. 70 | } 71 | 72 | int getLocalFieldNum() const { return mcLocalFields.length(); } 73 | int getFieldNum() const { return fieldNum; } 74 | IndexList getFieldIds() const { 75 | IndexList ret; 76 | for (int f = 0; f < fieldNum; f++) ret.add(mcFieldDesc[f]->id); 77 | return ret; 78 | } 79 | 80 | int getStepsPerCycle() const { 81 | return stepsPerCycle; 82 | } 83 | void setStepsPerCycle(int spc) { 84 | stepsPerCycle = spc; 85 | } 86 | 87 | // Pick a field node at random and twiddle it. 88 | TrialMove trialMove(bool local) { 89 | bool looking = true; 90 | double jump; 91 | double currVal; 92 | trialField = 0; 93 | 94 | while (looking) { 95 | // Pick the field randomly. 96 | if (fieldNum != 1) { 97 | if (local) trialField = mcLocalFields.get( int(rando->uniform()*mcLocalFields.length()) ); 98 | else trialField = int(rando->uniform()*fieldNum); 99 | } 100 | const FieldDesc* fd = mcFieldDesc[trialField]; 101 | 102 | // Pick the field node randomly. 103 | if (fd->fixedFile.length() == 0) 104 | // All nodes are free. 105 | trialNode = int(rando->uniform()*mcField[trialField]->length()); 106 | else { 107 | // Free nodes are specified in freeNodeList. 108 | int trialInd = int(rando->uniform()*fd->freeNodeList.length()); 109 | trialNode = fd->freeNodeList.get(trialInd); 110 | } 111 | 112 | // Choose the move. 113 | jump = fd->step*rando->student(1.0); 114 | 115 | // The move. 116 | currVal = mcField[trialField]->get(trialNode); 117 | trialVal = currVal + jump; 118 | 119 | // We immediately discard moves that violate the field limits. 120 | if (fd->hasMin && trialVal < fd->minVal) continue; 121 | if (fd->hasMax && trialVal > fd->maxVal) continue; 122 | looking = false; 123 | } 124 | 125 | // Make the trial move. 126 | trialLastVal = currVal; 127 | mcField[trialField]->set(trialNode, trialVal); 128 | 129 | Vector3 trialPos(0.0); 130 | // Limitation: Only the first three dimensions of the position are kept. 131 | trialPos.x = mcField[trialField]->nodePos(trialNode, 0); 132 | if ( mcField[trialField]->dimensions() >= 2 ) 133 | trialPos.y = mcField[trialField]->nodePos(trialNode, 1); 134 | if ( mcField[trialField]->dimensions() >= 3 ) 135 | trialPos.z = mcField[trialField]->nodePos(trialNode, 2); 136 | 137 | return TrialMove(mcFieldDesc[trialField]->id, trialNode, trialVal, trialLastVal, trialPos); 138 | } 139 | 140 | void reject() { 141 | // Revert the move. 142 | mcField[trialField]->set(trialNode, trialLastVal); 143 | } 144 | 145 | bool metropolis(double deltaCost) { 146 | if (deltaCost <= 0.0) return true; 147 | return (rando->uniform() < exp(-deltaCost)); 148 | } 149 | 150 | private: 151 | // Don't permit. 152 | MetroMonteCarlo(); 153 | MetroMonteCarlo(const MetroMonteCarlo&); 154 | void operator=(const MetroMonteCarlo&); 155 | }; 156 | #endif 157 | -------------------------------------------------------------------------------- /PiecewiseZero.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | #ifndef PIECEWISEZERO_H 14 | #define PIECEWISEZERO_H 15 | 16 | #include "useful.H" 17 | #include "Field.H" 18 | #include "Piecewise1d.H" 19 | 20 | class PiecewiseZero : public Piecewise1d { 21 | public: 22 | PiecewiseZero(const char* fileName, bool periodic0) { 23 | v0 = NULL; 24 | read(fileName, periodic0); 25 | } 26 | 27 | PiecewiseZero(const PiecewiseZero& tab) { 28 | n = tab.n; 29 | dr = tab.dr; 30 | dl = tab.dl; 31 | r0 = tab.r0; 32 | r1 = tab.r1; 33 | 34 | v0 = new double[n]; 35 | err = new double[n]; 36 | for (int i = 0; i < n; i++) { 37 | v0[i] = tab.v0[i]; 38 | err[i] = tab.err[i]; 39 | } 40 | e0 = tab.e0; 41 | periodic = tab.periodic; 42 | } 43 | 44 | PiecewiseZero(const double* dist, const double* pot, int n0, bool periodic0) { 45 | v0 = NULL; 46 | periodic = periodic0; 47 | init(dist, pot, n0); 48 | e0 = v0[n-1]; 49 | } 50 | 51 | PiecewiseZero(const double* pot, int n0, double x00, double dx0, bool periodic0) { 52 | n = abs(n0); 53 | dr = fabs(dx0); 54 | r0 = x00; 55 | r1 = r0 + n*dr; 56 | dl = r1 - r0; 57 | 58 | v0 = new double[n]; 59 | err = new double[n]; 60 | for (int i = 0; i < n; i++) { 61 | v0[i] = pot[i]; 62 | err[i] = 0.0; 63 | } 64 | e0 = v0[n-1]; 65 | } 66 | 67 | PiecewiseZero(double x0, double x1, double pot0, int n0, bool periodic0) { 68 | n = abs(n0); 69 | r0 = x0; 70 | r1 = x1; 71 | dl = r1-r0; 72 | dr = dl/n; 73 | periodic = periodic0; 74 | 75 | v0 = new double[n]; 76 | err = new double[n]; 77 | for (int i = 0; i < n; i++) { 78 | v0[i] = pot0; 79 | err[i] = 0.0; 80 | } 81 | e0 = v0[n-1]; 82 | } 83 | 84 | ~PiecewiseZero() { 85 | } 86 | 87 | PiecewiseZero& operator=(const PiecewiseZero& tab) { 88 | // Resize the arrays if necessary. 89 | if (n != tab.n) { 90 | delete[] v0; 91 | delete[] err; 92 | n = tab.n; 93 | v0 = new double[n]; 94 | err = new double[n]; 95 | } 96 | 97 | // Copy the values. 98 | for (int i = 0; i < n; i++) { 99 | v0[i] = tab.v0[i]; 100 | err[i] = tab.err[i]; 101 | } 102 | dr = tab.dr; 103 | dl = tab.dl; 104 | r0 = tab.r0; 105 | r1 = tab.r1; 106 | e0 = tab.e0; 107 | periodic = tab.periodic; 108 | 109 | return (*this); 110 | } 111 | 112 | static int countValueLines(const char* fileName) { 113 | FILE* inp = fopen(fileName, "r"); 114 | char line[STRLEN]; 115 | int count = 0; 116 | 117 | while (fgets(line, STRLEN, inp) != NULL) { 118 | // Ignore comments. 119 | int len = strlen(line); 120 | if (line[0] == '#') continue; 121 | if (len < 2) continue; 122 | 123 | count++; 124 | } 125 | fclose(inp); 126 | 127 | return count; 128 | } 129 | 130 | double getGrad(int j) const { 131 | if (j < 0 || j >= n) return 0.0; 132 | if (j == 0) return (v0[1]-v0[0])/dr; 133 | if (j == n-1) return (v0[n-1]-v0[n-2])/dr; 134 | return (v0[j+1]-v0[j-1])/(2.0*dr); 135 | } 136 | 137 | void scale(double s) { 138 | for (int i = 0; i < n; i++) { 139 | v0[i] *= s; 140 | } 141 | } 142 | 143 | double computeVal(double d) const { 144 | int home; 145 | 146 | if (periodic) { 147 | home = int(floor((wrap(d) - r0)/dr)); 148 | } else { 149 | home = int(floor((d - r0)/dr)); 150 | //printf("INSIDE home %d\n", home); 151 | if (home < 0) return v0[0]; 152 | else if (home >= n) return v0[n-1]; 153 | } 154 | 155 | return v0[home]; 156 | } 157 | 158 | double computeGrad(double d) const { 159 | return 0.0; 160 | } 161 | 162 | bool computeValGrad(double d, double& val, double& grad) const { 163 | val = computeVal(d); 164 | grad = 0.0; 165 | return true; 166 | } 167 | 168 | void zero() { 169 | for (int i = 0; i < n; i++) { 170 | v0[i] = 0.0; 171 | } 172 | } 173 | 174 | // Map. Don't forget to delete the returned value. 175 | // Map the values of 'srcVal' to the nodes of this. 176 | Field* map(const Field* srcVal) const { 177 | const PiecewiseZero* src = dynamic_cast(srcVal); 178 | if (src == NULL) { 179 | fprintf(stderr,"ERROR PiecewiseZero::map() requires fields of the same type.\n"); 180 | exit(-1); 181 | } 182 | 183 | PiecewiseZero* ret = new PiecewiseZero(*this); 184 | for (int i = 0; i < n; i++) { 185 | double x = getNodePos(i); 186 | double v = src->computeVal(x); 187 | int near = src->nearestNode(x); 188 | ret->v0[i] = v; 189 | ret->err[i] = src->err[near]; 190 | } 191 | 192 | return ret; 193 | } 194 | 195 | 196 | private: 197 | // Integrate over cell j. 198 | // Validation done in integrate(x0,x1). 199 | // The interpolant gives an exact solution. 200 | double integrate(int j) const { 201 | return dr*v0[j]; 202 | } 203 | // Integral from the home position rj to x0. 204 | // Validation done in integrate(x0,x1). 205 | double integrate(int j, double x) const { 206 | double rj = r0 + dr*j; 207 | double w = (x - rj)/dr; 208 | 209 | return dr*v0[j]*w; 210 | } 211 | 212 | void init(const double* dist, const double* pot, int n0) { 213 | n = abs(n0); 214 | dr = abs(dist[1]-dist[0]); 215 | r0 = dist[0]<=dist[1] ? dist[0] : dist[1]; 216 | r1 = r0 + n*dr; 217 | dl = r1 - r0; 218 | 219 | if (v0 != NULL) { 220 | delete[] v0; 221 | delete[] err; 222 | } 223 | 224 | v0 = new double[n]; 225 | err = new double[n]; 226 | for (int i = 0; i < n; i++) { 227 | v0[i] = pot[i]; 228 | err[i] = 0.0; 229 | } 230 | } 231 | 232 | // Interpolation functions do nothing since this is zero-order. 233 | void interpolation() {} 234 | void interpolation(int j) {} 235 | void makeInterpolant(int j) {} 236 | }; 237 | #endif 238 | -------------------------------------------------------------------------------- /RandomGsl.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | ///////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | // A wrapper for Gnu Scientific Library random number generators 14 | #ifndef RANDOMGSL_H 15 | #define RANDOMGSL_H 16 | 17 | #include 18 | #include 19 | 20 | class Random { 21 | 22 | private: 23 | gsl_rng* gslRando; 24 | 25 | public: 26 | 27 | // default constructor 28 | Random() { 29 | gslRando = gsl_rng_alloc(gsl_rng_mt19937); 30 | init(0); 31 | } 32 | 33 | // constructor with seed 34 | Random(unsigned long seed) { 35 | gslRando = gsl_rng_alloc(gsl_rng_mt19937); 36 | init(seed); 37 | } 38 | 39 | ~Random() { 40 | gsl_rng_free(gslRando); 41 | } 42 | 43 | // reinitialize with seed 44 | void init(unsigned long seed) { 45 | gsl_rng_set(gslRando, seed); 46 | } 47 | 48 | // return a number uniformly distributed between 0 and 1 49 | double uniform() { 50 | return gsl_rng_uniform(gslRando); 51 | } 52 | 53 | long poisson(double lambda) { 54 | return gsl_ran_poisson(gslRando, lambda); 55 | } 56 | 57 | // return a number from a standard gaussian distribution 58 | double gaussian() { 59 | return gsl_ran_ugaussian(gslRando); 60 | } 61 | 62 | // return a random long 63 | long integer() { 64 | return gsl_rng_get(gslRando); 65 | } 66 | 67 | // Student's t-distribution. 68 | double student(double nu) { 69 | return gsl_ran_tdist(gslRando, nu); 70 | } 71 | 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /SolutionStruct.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef SOLUTIONSTRUCT_H 13 | #define SOLUTIONSTRUCT_H 14 | 15 | struct SolutionStruct { 16 | public: 17 | int n; 18 | double dx, dxSq, x0; 19 | bool periodic; 20 | double timestep; 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /TrajComer.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJCOMER_H 13 | #define TRAJCOMER_H 14 | 15 | #include 16 | #include "useful.H" 17 | #include "Field.H" 18 | #include "PiecewiseLinear.H" 19 | #include "PiecewiseCubic.H" 20 | #include "Event.H" 21 | #include "TrajCostComputer.H" 22 | 23 | class TrajComer : public TrajCostComputer { 24 | private: 25 | const Piecewise1d* diffuse; 26 | const Piecewise1d* force; 27 | int T, X, D, FB; 28 | 29 | public: 30 | TrajComer(const TrajCostDesc& tcd) : 31 | TrajCostComputer(tcd, 4) { 32 | 33 | if (fieldSel.length() != 2) { 34 | fprintf(stderr, "ERROR trajCost ccg takes two fields: (0) diffusivity (1) force\n"); 35 | exit(-1); 36 | } 37 | 38 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 39 | if (diffuse == NULL) { 40 | fprintf(stderr,"ERROR trajCost ccg requires field type linear or cubic.\n"); 41 | exit(-1); 42 | } 43 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 44 | if (force == NULL) { 45 | fprintf(stderr,"ERROR trajCost ccg requires field type linear or cubic.\n"); 46 | exit(-1); 47 | } 48 | 49 | T = 1; 50 | X = 0; 51 | D = 0; 52 | FB = 2; 53 | 54 | updateLocal(); 55 | cloneLast(); 56 | } 57 | 58 | // Event variables. 59 | void eventVarShortcuts() { 60 | T = eventIndList[0]; 61 | X = eventIndList[1]; 62 | D = eventIndList[2]; 63 | FB = eventIndList[3]; 64 | //for (int i = 0; i < 4; i++) printf("eventIndList[%d] = %d\n", i, eventIndList[i]); 65 | } 66 | // Event variables. 67 | String eventVarName(int ind) const { 68 | switch(ind) { 69 | case 0: 70 | return String("time"); 71 | case 1: 72 | return String("pos"); 73 | case 2: 74 | return String("displacement"); 75 | case 3: 76 | return String("forceBias"); 77 | default: 78 | return String("UNKNOWN"); 79 | } 80 | } 81 | 82 | String fieldName(int ind) const { 83 | switch(ind) { 84 | case 0: 85 | return String("diffusivity"); 86 | case 1: 87 | return String("force"); 88 | default: 89 | return String("UNKNOWN"); 90 | } 91 | } 92 | 93 | 94 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 95 | inline double ccgCost(double dt, double dx, double frc, double dif, double gradDif) { 96 | // Store the data that can be used to reconstruct gt. 97 | double gtNumer0 = dx - beta*dif*frc*dt - gradDif*dt; 98 | double gtVar0 = 2.0*dif*dt; 99 | // Avoid race conditions. 100 | gtNumer = gtNumer0; 101 | gtVar = gtVar0; 102 | 103 | //printf("dt %g\n", dt); 104 | 105 | return 0.5*log(2.0*M_PI*gtVar0) + 0.5*(gtNumer0*gtNumer0)/gtVar0; 106 | } 107 | 108 | double eventCost(int e) { 109 | // Sum of forceBias and forceSys. 110 | double frc = event[e].var[FB] + force->computeVal(event[e].var[X]); 111 | // The diffusivity and its gradient. 112 | double dif, gradDif; 113 | diffuse->computeValGrad(event[e].var[X], dif, gradDif); 114 | // Give a huge result for negative diffusivities. 115 | if (dif <= 0.0) return std::numeric_limits::max(); 116 | 117 | // Add the cost of this event. 118 | double cost = ccgCost(event[e].del[T], event[e].del[D], frc, dif, gradDif); 119 | 120 | // Check for NaN. 121 | #ifdef FUSION_DEBUG 122 | //printf("e %d x %g dif %g %g %g\n", e, event[e].var[X], diffuse->computeVal(1.0), diffuse->computeZeroOrder(1.0), diffuse->get(12)); 123 | nanCheck(cost,'e',e,event[e].del[D],frc,gradDif,dif); 124 | #endif 125 | return cost; 126 | } 127 | }; 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /TrajComer2d.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJCOMER2D_H 13 | #define TRAJCOMER2D_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseBicubic.H" 18 | #include "Event.H" 19 | #include "TrajCostComputer.H" 20 | 21 | class TrajComer2d : public TrajCostComputer { 22 | private: 23 | const PiecewiseBicubic* diffuse; 24 | const PiecewiseBicubic* force; 25 | int T, X, Y, D, FB; 26 | int dimension; 27 | 28 | public: 29 | TrajComer2d(const TrajCostDesc& tcd) : 30 | TrajCostComputer(tcd, 5), dimension(tcd.dimension) { 31 | 32 | if (fieldSel.length() != 2) { 33 | fprintf(stderr, "ERROR trajCost ccg2d takes two fields: (0) diffusivity (1) force \n"); 34 | exit(-1); 35 | } 36 | 37 | if (dimension != 0 && dimension != 1) { 38 | fprintf(stderr, "ERROR trajCost ccg2d: dimension must be 0 or 1 not %d\n", dimension); 39 | exit(-1); 40 | } 41 | 42 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 43 | if (diffuse == NULL) { 44 | fprintf(stderr,"ERROR trajCost ccg2d requires field type bicubic.\n"); 45 | exit(-1); 46 | } 47 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 48 | if (force == NULL) { 49 | fprintf(stderr,"ERROR trajCost ccg2d requires field type bicubic.\n"); 50 | exit(-1); 51 | } 52 | 53 | T = 2; 54 | X = 0; 55 | Y = 1; 56 | D = 0; 57 | FB = 3; 58 | 59 | updateLocal(); 60 | cloneLast(); 61 | } 62 | 63 | // Event variables. 64 | void eventVarShortcuts() { 65 | T = eventIndList[0]; 66 | X = eventIndList[1]; 67 | Y = eventIndList[2]; 68 | D = eventIndList[3]; 69 | FB = eventIndList[4]; 70 | for (int i = 0; i < 5; i++) printf("eventIndList[%d] = %d %s\n", i, eventIndList[i], eventVarName(i).cs()); 71 | } 72 | // Event variables. 73 | String eventVarName(int ind) const { 74 | switch(ind) { 75 | case 0: 76 | return String("time"); 77 | case 1: 78 | return String("posX"); 79 | case 2: 80 | return String("posY"); 81 | case 3: 82 | return String("displacement"); 83 | case 4: 84 | return String("forceBias"); 85 | default: 86 | return String("UNKNOWN"); 87 | } 88 | } 89 | 90 | String fieldName(int ind) const { 91 | switch(ind) { 92 | case 0: 93 | return String("diffusivity"); 94 | case 1: 95 | return String("force"); 96 | default: 97 | return String("UNKNOWN"); 98 | } 99 | } 100 | 101 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 102 | inline double ccgCost(double dt, double dx, double frc, double dif, double gradDif) { 103 | // Store the data that can be used to reconstruct gt. 104 | double gtNumer0 = dx - beta*dif*frc*dt - gradDif*dt; 105 | double gtVar0 = 2.0*dif*dt; 106 | // Avoid race conditions. 107 | gtNumer = gtNumer0; 108 | gtVar = gtVar0; 109 | 110 | //printf("dt %g\n", dt); 111 | 112 | return 0.5*log(2.0*M_PI*gtVar0) + 0.5*(gtNumer0*gtNumer0)/gtVar0; 113 | } 114 | 115 | double eventCost(int e) { 116 | // Sum of forceBias and forceSys. 117 | double frc = event[e].var[FB] + force->computeVal(event[e].var[X], event[e].var[Y]); 118 | // The diffusivity and its gradient. 119 | double dif = diffuse->computeVal(event[e].var[X], event[e].var[Y]); 120 | double gradDif = diffuse->computeGrad(dimension, event[e].var[X], event[e].var[Y]); 121 | 122 | // Add the cost of this event. 123 | return ccgCost(event[e].del[T], event[e].del[D], frc, dif, gradDif); 124 | } 125 | }; 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /TrajComer2d2d.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJCOMER2D2D_H 13 | #define TRAJCOMER2D2D_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseBicubic.H" 18 | #include "Event.H" 19 | #include "TrajCostComputer.H" 20 | 21 | class TrajComer2d2d : public TrajCostComputer { 22 | private: 23 | const PiecewiseBicubic* diffuse; 24 | const PiecewiseBicubic* forceX; 25 | const PiecewiseBicubic* forceY; 26 | int T, X, Y, DX, DY, FBX, FBY; 27 | double invSqrt2; 28 | 29 | public: 30 | TrajComer2d2d(const Field** ppf, IndexList fieldSel0, const Event* event0, int eventNum0, double kt, int leastLocal) : 31 | TrajCostComputer(ppf, fieldSel0, event0, eventNum0, kt, leastLocal, 7), invSqrt2(1.0/sqrt(2.0)) { 32 | 33 | if (tcFieldNum != 2) { 34 | fprintf(stderr, "ERROR trajCost ccg2d2d takes three fields: (0) diffusivity (1) forceX (2) forceY \n"); 35 | exit(-1); 36 | } 37 | 38 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 39 | if (diffuse == NULL) { 40 | fprintf(stderr,"ERROR trajCost ccg2d2d requires field type bicubic.\n"); 41 | exit(-1); 42 | } 43 | forceX = dynamic_cast(fieldList[fieldSel.get(1)]); 44 | if (forceX == NULL) { 45 | fprintf(stderr,"ERROR trajCost ccg2d2d requires field type bicubic.\n"); 46 | exit(-1); 47 | } 48 | forceY = dynamic_cast(fieldList[fieldSel.get(1)]); 49 | if (forceY == NULL) { 50 | fprintf(stderr,"ERROR trajCost ccg2d2d requires field type bicubic.\n"); 51 | exit(-1); 52 | } 53 | 54 | T = 2; 55 | X = 0; 56 | Y = 1; 57 | DX = 0; 58 | DY = 1; 59 | FBX = 3; 60 | FBY = 4; 61 | 62 | updateLocal(); 63 | cloneLast(); 64 | } 65 | 66 | // Event variables. 67 | void eventVarShortcuts() { 68 | T = eventIndList[0]; 69 | X = eventIndList[1]; 70 | Y = eventIndList[2]; 71 | DX = eventIndList[3]; 72 | DY = eventIndList[4]; 73 | FBX = eventIndList[5]; 74 | FBY = eventIndList[6]; 75 | for (int i = 0; i < 7; i++) printf("eventIndList[%d] = %d\n", i, eventIndList[i]); 76 | } 77 | // Event variables. 78 | String eventVarName(int ind) const { 79 | switch(ind) { 80 | case 0: 81 | return String("time"); 82 | case 1: 83 | return String("posX"); 84 | case 2: 85 | return String("posY"); 86 | case 3: 87 | return String("displacementX"); 88 | case 4: 89 | return String("displacementY"); 90 | case 5: 91 | return String("forceBiasX"); 92 | case 6: 93 | return String("forceBiasY"); 94 | default: 95 | return String("UNKNOWN"); 96 | } 97 | } 98 | 99 | String fieldName(int ind) const { 100 | switch(ind) { 101 | case 0: 102 | return String("diffusivity"); 103 | case 1: 104 | return String("forceX"); 105 | case 2: 106 | return String("forceY"); 107 | default: 108 | return String("UNKNOWN"); 109 | } 110 | } 111 | 112 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 113 | inline double ccgCost(double dt, double dx, double dy, double fx, double fy, double dif, double gradDifX, double gradDifY) { 114 | // Extra factor of two for cylindrical coordinates is probably approximate. 115 | double muX = dx - beta*dif*fx*dt - gradDifX*dt; 116 | double muY = dy - beta*dif*fy*dt - gradDifY*dt; 117 | // Store the data that can be used to reconstruct gt. 118 | gtNumer = (muX + muY)*invSqrt2; 119 | double gtVar0 = 2.0*dif*dt; 120 | // Avoid race conditions. 121 | gtVar = gtVar0; 122 | 123 | // Note that there's a factor of 2 on the first term. 124 | return log(2.0*M_PI*gtVar0) + 0.5*(muX*muX + muY*muY)/gtVar0; 125 | } 126 | 127 | double eventCost(int e) { 128 | // Sum of forceBias and forceSys. 129 | double fx = event[e].var[FBX] + forceX->computeVal(event[e].var[X], event[e].var[Y]); 130 | double fy = event[e].var[FBY] + forceY->computeVal(event[e].var[X], event[e].var[Y]); 131 | // The diffusivity and its gradient. 132 | double dif = diffuse->computeVal(event[e].var[X], event[e].var[Y]); 133 | double gradDifX = diffuse->computeGradX(event[e].var[X], event[e].var[Y]); 134 | double gradDifY = diffuse->computeGradY(event[e].var[X], event[e].var[Y]); 135 | 136 | // Add the cost of this event. 137 | return ccgCost(event[e].del[T], event[e].del[DX], event[e].del[DY], fx, fy, dif, gradDifX, gradDifY); 138 | } 139 | }; 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /TrajComer2d2d2d.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJCOMER2D2D2D_H 13 | #define TRAJCOMER2D2D2D_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseBicubic.H" 18 | #include "Event.H" 19 | #include "TrajCostComputer.H" 20 | 21 | class TrajComer2d2d2d : public TrajCostComputer { 22 | private: 23 | const PiecewiseBicubic* diffuseX; 24 | const PiecewiseBicubic* diffuseY; 25 | const PiecewiseBicubic* forceX; 26 | const PiecewiseBicubic* forceY; 27 | int T, X, Y, DX, DY, FBX, FBY; 28 | double invSqrt2; 29 | 30 | public: 31 | TrajComer2d2d2d(const Field** ppf, IndexList fieldSel0, const Event* event0, int eventNum0, double kt, int leastLocal) : 32 | TrajCostComputer(ppf, fieldSel0, event0, eventNum0, kt, leastLocal, 7), invSqrt2(1.0/sqrt(2.0)) { 33 | 34 | if (tcFieldNum != 4) { 35 | fprintf(stderr, "ERROR trajCost ccg2d2d2d takes four fields: (0) diffuseX (1) diffuseY (2) forceX (3) forceY \n"); 36 | exit(-1); 37 | } 38 | 39 | diffuseX = dynamic_cast(fieldList[fieldSel.get(0)]); 40 | if (diffuseX == NULL) { 41 | fprintf(stderr,"ERROR trajCost ccg2d2d2d requires field type bicubic.\n"); 42 | exit(-1); 43 | } 44 | diffuseY = dynamic_cast(fieldList[fieldSel.get(1)]); 45 | if (diffuseY == NULL) { 46 | fprintf(stderr,"ERROR trajCost ccg2d2d2d requires field type bicubic.\n"); 47 | exit(-1); 48 | } 49 | forceX = dynamic_cast(fieldList[fieldSel.get(2)]); 50 | if (forceX == NULL) { 51 | fprintf(stderr,"ERROR trajCost ccg2d2d2d requires field type bicubic.\n"); 52 | exit(-1); 53 | } 54 | forceY = dynamic_cast(fieldList[fieldSel.get(3)]); 55 | if (forceY == NULL) { 56 | fprintf(stderr,"ERROR trajCost ccg2d2d2d requires field type bicubic.\n"); 57 | exit(-1); 58 | } 59 | 60 | T = 2; 61 | X = 0; 62 | Y = 1; 63 | DX = 0; 64 | DY = 1; 65 | FBX = 3; 66 | FBY = 4; 67 | 68 | updateLocal(); 69 | cloneLast(); 70 | } 71 | 72 | // Event variables. 73 | void eventVarShortcuts() { 74 | T = eventIndList[0]; 75 | X = eventIndList[1]; 76 | Y = eventIndList[2]; 77 | DX = eventIndList[3]; 78 | DY = eventIndList[4]; 79 | FBX = eventIndList[5]; 80 | FBY = eventIndList[6]; 81 | for (int i = 0; i < 7; i++) printf("eventIndList[%d] = %d\n", i, eventIndList[i]); 82 | } 83 | // Event variables. 84 | String eventVarName(int ind) const { 85 | switch(ind) { 86 | case 0: 87 | return String("time"); 88 | case 1: 89 | return String("posX"); 90 | case 2: 91 | return String("posY"); 92 | case 3: 93 | return String("displacementX"); 94 | case 4: 95 | return String("displacementY"); 96 | case 5: 97 | return String("forceBiasX"); 98 | case 6: 99 | return String("forceBiasY"); 100 | default: 101 | return String("UNKNOWN"); 102 | } 103 | } 104 | 105 | String fieldName(int ind) const { 106 | switch(ind) { 107 | case 0: 108 | return String("diffuseX"); 109 | case 1: 110 | return String("diffuseY"); 111 | case 2: 112 | return String("forceX"); 113 | case 3: 114 | return String("forceY"); 115 | default: 116 | return String("UNKNOWN"); 117 | } 118 | } 119 | 120 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 121 | inline double ccgCost(double dt, double dx, double frc, double dif, double gradDif) { 122 | // Store the data that can be used to reconstruct gt. 123 | double gtNumer0 = dx - beta*dif*frc*dt - gradDif*dt; 124 | double gtVar0 = 2.0*dif*dt; 125 | // Avoid race conditions. 126 | gtNumer = gtNumer0; 127 | gtVar = gtVar0; 128 | 129 | return 0.5*log(2.0*M_PI*gtVar0) + 0.5*(gtNumer0*gtNumer0)/gtVar0; 130 | } 131 | 132 | double eventCost(int e) { 133 | // Sum of forceBias and forceSys. 134 | double fx = event[e].var[FBX] + forceX->computeVal(event[e].var[X], event[e].var[Y]); 135 | double fy = event[e].var[FBY] + forceY->computeVal(event[e].var[X], event[e].var[Y]); 136 | // The diffusivity and its gradient. 137 | double difX = diffuseX->computeVal(event[e].var[X], event[e].var[Y]); 138 | double gradDifX = diffuseX->computeGradX(event[e].var[X], event[e].var[Y]); 139 | double difY = diffuseY->computeVal(event[e].var[X], event[e].var[Y]); 140 | double gradDifY = diffuseY->computeGradY(event[e].var[X], event[e].var[Y]); 141 | 142 | // Add the cost of this event. 143 | double cost = ccgCost(event[e].del[T], event[e].del[DX], fx, difX, gradDifX); 144 | cost += ccgCost(event[e].del[T], event[e].del[DY], fy, difY, gradDifY); 145 | return cost; 146 | } 147 | }; 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /TrajComerLog.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJCOMERLOG_H 13 | #define TRAJCOMERLOG_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseLinear.H" 18 | #include "PiecewiseCubic.H" 19 | #include "Event.H" 20 | #include "TrajCostComputer.H" 21 | 22 | class TrajComerLog : public TrajCostComputer { 23 | private: 24 | const Piecewise1d* logDiffuse; 25 | const Piecewise1d* force; 26 | int T, X, D, FB; 27 | 28 | public: 29 | TrajComerLog(const Field** ppf, IndexList fieldSel0, const Event* event0, int eventNum0, double kt, int leastLocal) : 30 | TrajCostComputer(ppf, fieldSel0, event0, eventNum0, kt, leastLocal, 4) { 31 | 32 | if (tcFieldNum != 2) { 33 | fprintf(stderr, "ERROR trajCost ccgLog takes two fields: (0) log_diffuisivity (1) force\n"); 34 | exit(-1); 35 | } 36 | 37 | logDiffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 38 | if (logDiffuse == NULL) { 39 | fprintf(stderr,"ERROR trajCostLog ccg requires field type linear or cubic.\n"); 40 | exit(-1); 41 | } 42 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 43 | if (force == NULL) { 44 | fprintf(stderr,"ERROR trajCostLog ccg requires field type linear or cubic.\n"); 45 | exit(-1); 46 | } 47 | 48 | T = 1; 49 | X = 0; 50 | D = 0; 51 | FB = 2; 52 | 53 | updateLocal(); 54 | cloneLast(); 55 | } 56 | 57 | // Event variables. 58 | void eventVarShortcuts() { 59 | T = eventIndList[0]; 60 | X = eventIndList[1]; 61 | D = eventIndList[2]; 62 | FB = eventIndList[3]; 63 | for (int i = 0; i < 4; i++) printf("eventIndList[%d] = %d\n", i, eventIndList[i]); 64 | } 65 | // Event variables. 66 | String eventVarName(int ind) const { 67 | switch(ind) { 68 | case 0: 69 | return String("time"); 70 | case 1: 71 | return String("pos"); 72 | case 2: 73 | return String("displacement"); 74 | case 3: 75 | return String("forceBias"); 76 | default: 77 | return String("UNKNOWN"); 78 | } 79 | } 80 | 81 | String fieldName(int ind) const { 82 | switch(ind) { 83 | case 0: 84 | return String("diffusivity"); 85 | case 1: 86 | return String("force"); 87 | default: 88 | return String("UNKNOWN"); 89 | } 90 | } 91 | 92 | 93 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 94 | inline double ccgCost(double dt, double dx, double frc, double dif, double gradDif) { 95 | // Store the data that can be used to reconstruct gt. 96 | double gtNumer0 = dx - beta*dif*frc*dt - gradDif*dt; 97 | double gtVar0 = 2.0*dif*dt; 98 | // Avoid race conditions. 99 | gtNumer = gtNumer0; 100 | gtVar = gtVar0; 101 | 102 | //printf("dt %g\n", dt); 103 | 104 | return 0.5*log(2.0*M_PI*gtVar0) + 0.5*(gtNumer0*gtNumer0)/gtVar0; 105 | } 106 | 107 | double eventCost(int e) { 108 | // Sum of forceBias and forceSys. 109 | double frc = event[e].var[FB] + force->computeVal(event[e].var[X]); 110 | // The diffusivity and its gradient. 111 | double logDif, gradLogDif; 112 | logDiffuse->computeValGrad(event[e].var[X], logDif, gradLogDif); 113 | double dif = exp(logDif); 114 | double gradDif = dif*gradLogDif; 115 | 116 | // Add the cost of this event. 117 | double cost = ccgCost(event[e].del[T], event[e].del[D], frc, dif, gradDif); 118 | 119 | // Check for NaN. 120 | #ifdef FUSION_DEBUG 121 | nanCheck(cost,'e',e,event[e].del[D],frc,gradDif,dif); 122 | #endif 123 | 124 | return cost; 125 | } 126 | }; 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /TrajCostDesc.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | // A TrajCostComputer descriptor 14 | 15 | #ifndef TRAJCOSTDESC_H 16 | #define TRAJCOSTDESC_H 17 | 18 | #include "Field.H" 19 | #include "Event.H" 20 | 21 | struct TrajCostDesc { 22 | public: 23 | Field** fieldList; // Pointer to array of fields. 24 | IndexList fieldSel; // Indices of fields associated with this TrajCostComputer 25 | Event* event; // Pointer to array of events. 26 | int eventNum; // Total number of events. 27 | double kbt; // Thermal energy 28 | int leastLocal; // Index of the least local field in fieldList 29 | int group; // TrajCostComputer applies to events with this group (-1 means all events). 30 | int dimension; // Dimension along which we compute the displacement 31 | double timestep; // Timestep of Smoluchowski integration 32 | double maxHop; // Largest number of nodes hopped in a Smoluchowski solution (time delta t) 33 | double weight; // Multiply the cost by this factor 34 | 35 | TrajCostDesc(Field** fieldList0, Event* event0, int eventNum0) : 36 | fieldList(fieldList0), event(event0), eventNum(eventNum0), kbt(1.0), 37 | leastLocal(-1), group(0), dimension(-1), timestep(-1.0), maxHop(-1.0), weight(1.0) 38 | { 39 | } 40 | private: 41 | // Force use of the constructor above. 42 | TrajCostDesc() { } 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /TrajFilter.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | // An object for filtering trajectory data. 14 | 15 | #ifndef TRAJFILTER_H 16 | #define TRAJFILTER_H 17 | 18 | class TrajFilter { 19 | private: 20 | int cap; 21 | int minNum; 22 | int* minVar; 23 | double* minVal; 24 | int maxNum; 25 | int* maxVar; 26 | double* maxVal; 27 | int scaleNum; 28 | int* scaleVar; 29 | double* scaleVal; 30 | int periodicNum; 31 | int* periodicVar; 32 | double* periodicMin; 33 | double* periodicMax; 34 | public: 35 | TrajFilter(int cap0) : cap(cap0), minNum(0), maxNum(0), scaleNum(0), periodicNum(0) { 36 | minVar = new int[cap]; 37 | minVal = new double[cap]; 38 | maxVar = new int[cap]; 39 | maxVal = new double[cap]; 40 | scaleVar = new int[cap]; 41 | scaleVal = new double[cap]; 42 | periodicVar = new int[cap]; 43 | periodicMin = new double[cap]; 44 | periodicMax = new double[cap]; 45 | } 46 | ~TrajFilter() { 47 | delete[] minVar; 48 | delete[] minVal; 49 | delete[] maxVar; 50 | delete[] maxVal; 51 | delete[] scaleVar; 52 | delete[] scaleVal; 53 | delete[] periodicVar; 54 | delete[] periodicMin; 55 | delete[] periodicMax; 56 | } 57 | 58 | double getMinNum() const { return minNum; } 59 | double getMaxNum() const { return maxNum; } 60 | double getScaleNum() const { return scaleNum; } 61 | double getPeriodicNum() const { return periodicNum; } 62 | // No bounds checking here. 63 | double getMinVal(int i) const { return minVal[i]; } 64 | double getMaxVal(int i) const { return maxVal[i]; } 65 | double getScaleVal(int i) const { return scaleVal[i]; } 66 | double getPeriodicMin(int i) const { return periodicMin[i]; } 67 | double getPeriodicMax(int i) const { return periodicMax[i]; } 68 | int getMinVar(int i) const { return minVar[i]; } 69 | int getMaxVar(int i) const { return maxVar[i]; } 70 | int getScaleVar(int i) const { return scaleVar[i]; } 71 | int getPeriodicVar(int i) const { return periodicVar[i]; } 72 | 73 | bool addMin(int var, double val) { 74 | if (minNum >= cap) return false; 75 | minVar[minNum] = var; 76 | minVal[minNum] = val; 77 | minNum++; 78 | return true; 79 | } 80 | bool addMax(int var, double val) { 81 | if (maxNum >= cap) return false; 82 | maxVar[maxNum] = var; 83 | maxVal[maxNum] = val; 84 | maxNum++; 85 | return true; 86 | } 87 | bool addScale(int var, double val) { 88 | if (scaleNum >= cap) return false; 89 | scaleVar[scaleNum] = var; 90 | scaleVal[scaleNum] = val; 91 | scaleNum++; 92 | return true; 93 | } 94 | bool addPeriodic(int var, double pMin, double pMax) { 95 | if (periodicNum >= cap) return false; 96 | periodicVar[periodicNum] = var; 97 | periodicMin[periodicNum] = pMin; 98 | periodicMax[periodicNum] = pMax; 99 | periodicNum++; 100 | return true; 101 | } 102 | 103 | String toString() const { 104 | char s[STRLEN]; 105 | snprintf(s, STRLEN, "filter.min %d filter.max %d filter.scale %d filter.periodic %d", minNum, maxNum, scaleNum, periodicNum); 106 | return String(s); 107 | } 108 | private: 109 | // Don't permit. 110 | TrajFilter(); 111 | TrajFilter(const TrajFilter&); 112 | void operator=(const TrajFilter&); 113 | }; 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /TrajFoxFunction.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJFRACTIONAL_H 13 | #define TRAJFRACTIONAL_H 14 | 15 | #include 16 | #include "useful.H" 17 | #include "Field.H" 18 | #include "PiecewiseLinear.H" 19 | #include "PiecewiseCubic.H" 20 | #include "FoxFunc.H" 21 | #include "Event.H" 22 | #include "TrajCostComputer.H" 23 | 24 | class TrajFoxFunction : public TrajCostComputer { 25 | private: 26 | const Piecewise1d* diffuse; 27 | const Piecewise1d* force; 28 | const Piecewise1d* alpha; // Anomalous diffusion exponent 29 | int T, X, D, FB; 30 | FoxFunc fox; 31 | 32 | public: 33 | TrajFoxFunction(const Field** ppf, IndexList fieldSel0, const Event* event0, int eventNum0, double kt, int leastLocal) : 34 | TrajCostComputer(ppf, fieldSel0, event0, eventNum0, kt, leastLocal, 4), 35 | fox(100) { 36 | 37 | if (tcFieldNum != 3) { 38 | fprintf(stderr, "ERROR trajCost fractional takes three fields: (0) diffusivity (1) force (2) anomalous_diffusion_exponent\n"); 39 | exit(-1); 40 | } 41 | 42 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 43 | if (diffuse == NULL) { 44 | fprintf(stderr,"ERROR trajCost fractional requires field type linear or cubic.\n"); 45 | exit(-1); 46 | } 47 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 48 | if (force == NULL) { 49 | fprintf(stderr,"ERROR trajCost fractional requires field type linear or cubic.\n"); 50 | exit(-1); 51 | } 52 | alpha = dynamic_cast(fieldList[fieldSel.get(2)]); 53 | if (alpha == NULL) { 54 | fprintf(stderr,"ERROR trajCost fractional requires field type linear or cubic.\n"); 55 | exit(-1); 56 | } 57 | 58 | T = 1; 59 | X = 0; 60 | D = 0; 61 | FB = 2; 62 | 63 | updateLocal(); 64 | cloneLast(); 65 | } 66 | 67 | // Event variables. 68 | void eventVarShortcuts() { 69 | T = eventIndList[0]; 70 | X = eventIndList[1]; 71 | D = eventIndList[2]; 72 | FB = eventIndList[3]; 73 | for (int i = 0; i < 4; i++) printf("eventIndList[%d] = %d\n", i, eventIndList[i]); 74 | } 75 | // Event variables. 76 | String eventVarName(int ind) const { 77 | switch(ind) { 78 | case 0: 79 | return String("time"); 80 | case 1: 81 | return String("pos"); 82 | case 2: 83 | return String("displacement"); 84 | case 3: 85 | return String("forceBias"); 86 | default: 87 | return String("UNKNOWN"); 88 | } 89 | } 90 | 91 | String fieldName(int ind) const { 92 | switch(ind) { 93 | case 0: 94 | return String("diffusivity"); 95 | case 1: 96 | return String("force"); 97 | case 2: 98 | return String("alpha"); 99 | default: 100 | return String("UNKNOWN"); 101 | } 102 | } 103 | 104 | 105 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 106 | inline double ccgCost(double dt, double dx, double frc, double dif, double gradDif) { 107 | // Store the data that can be used to reconstruct gt. 108 | double gtNumer0 = dx - beta*dif*frc*dt - gradDif*dt; 109 | double gtVar0 = 2.0*dif*dt; 110 | // Avoid race conditions. 111 | gtNumer = gtNumer0; 112 | gtVar = gtVar0; 113 | 114 | return 0.5*log(2.0*M_PI*gtVar0) + 0.5*(gtNumer0*gtNumer0)/gtVar0; 115 | } 116 | 117 | // The heart of the method: Equation 46 of Metzler and Klafter 118 | inline double fracCost(double dt, double dx, double frc, double dif, double gradDif, double alpha) { 119 | //printf("dt %g dx %g frc %g dif %g gradDif %g alpha %g\n", dt, dx, frc, dif, gradDif, alpha); 120 | double w = fox.w(dx, alpha, dif, dt); 121 | //if ( w != w || w<1e-300 ) printf("numerical problem with fox.w() %.15g\n", w); 122 | return -log(w); 123 | } 124 | 125 | double eventCost(int e) { 126 | // Sum of forceBias and forceSys. 127 | double frc = event[e].var[FB] + force->computeVal(event[e].var[X]); 128 | // The diffusivity and its gradient. 129 | double dif, gradDif; 130 | diffuse->computeValGrad(event[e].var[X], dif, gradDif); 131 | // Give a huge result for negative diffusivities. 132 | if (dif <= 0.0) return std::numeric_limits::max(); 133 | 134 | /// TESTING 135 | // Zero-out gradDif. 136 | gradDif = 0.0; 137 | 138 | // The anomalous diffusion exponent. 139 | double a = alpha->computeVal(event[e].var[X]); 140 | 141 | // Add the cost of this event. 142 | double cost = fracCost(event[e].del[T], event[e].del[D], frc, dif, gradDif, a); 143 | 144 | // Check for NaN. 145 | #ifdef FUSION_DEBUG 146 | //printf("e %d x %g dif %g %g %g\n", e, event[e].var[X], diffuse->computeVal(1.0), diffuse->computeZeroOrder(1.0), diffuse->get(12)); 147 | nanCheck(cost,'e',e,event[e].del[D],frc,gradDif,dif); 148 | #endif 149 | return cost; 150 | } 151 | }; 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /TrajReflect.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJREFLECT_H 13 | #define TRAJREFLECT_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseCubic.H" 18 | #include "Event.H" 19 | #include "TrajCostComputer.H" 20 | 21 | //#include 22 | 23 | class TrajReflect : public TrajCostComputer { 24 | private: 25 | const Piecewise1d* diffuse; 26 | const Piecewise1d* force; 27 | int T, X, D, FB; 28 | double bound0; 29 | double bound1; 30 | 31 | public: 32 | TrajReflect(const TrajCostDesc& tcd) : 33 | TrajCostComputer(tcd, 4) { 34 | 35 | if (fieldSel.length() != 2) { 36 | fprintf(stderr, "ERROR trajCost reflect takes two fields: (0) diffusivity (1) force \n"); 37 | exit(-1); 38 | } 39 | 40 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 41 | if (diffuse == NULL) { 42 | fprintf(stderr,"ERROR trajCost reflect requires field type linear or cubic.\n"); 43 | exit(-1); 44 | } 45 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 46 | if (force == NULL) { 47 | fprintf(stderr,"ERROR trajCost reflect requires field type linear or cubic.\n"); 48 | exit(-1); 49 | } 50 | 51 | // Set the boundary based on the diffusivity field and the dimension. 52 | bound0 = diffuse->getR0(); 53 | bound1 = diffuse->getR1(); 54 | 55 | T = 1; 56 | X = 0; 57 | D = 0; 58 | FB = 2; 59 | 60 | updateLocal(); 61 | cloneLast(); 62 | } 63 | 64 | // Event variables. 65 | void eventVarShortcuts() { 66 | T = eventIndList[0]; 67 | X = eventIndList[1]; 68 | D = eventIndList[2]; 69 | FB = eventIndList[3]; 70 | for (int i = 0; i < 4; i++) printf("eventIndList[%d] = %d %s\n", i, eventIndList[i], eventVarName(i).cs()); 71 | } 72 | // Event variables. 73 | String eventVarName(int ind) const { 74 | switch(ind) { 75 | case 0: 76 | return String("time"); 77 | case 1: 78 | return String("pos"); 79 | case 2: 80 | return String("displacement"); 81 | case 3: 82 | return String("forceBias"); 83 | default: 84 | return String("UNKNOWN"); 85 | } 86 | } 87 | 88 | String fieldName(int ind) const { 89 | switch(ind) { 90 | case 0: 91 | return String("diffusivity"); 92 | case 1: 93 | return String("force"); 94 | default: 95 | return String("UNKNOWN"); 96 | } 97 | } 98 | 99 | double reflectCost(double dt, double dx, double frc, double dif, double gradDif, double x0, double xa, double xb) { 100 | // Store the data that can be used to reconstruct gt. 101 | double mu = (beta*dif*frc + gradDif)*dt; 102 | double var = 2.0*dif*dt; 103 | double alpha = 0.5/var; 104 | 105 | double x1 = x0 + dx; 106 | double gtNumer0 = dx - mu; 107 | double plus = x1 + x0 - mu; 108 | double numer1 = plus - 2.0*xa; 109 | double numer2 = plus + 2.0*xb; 110 | 111 | double sum = exp(-alpha*gtNumer0*gtNumer0); 112 | sum += exp(-alpha*numer1*numer1); 113 | sum += exp(-alpha*numer2*numer2); 114 | 115 | // Avoid race conditions. 116 | gtNumer = gtNumer0; 117 | gtVar = var; 118 | 119 | return 0.5*log(2.0*M_PI*var) - log(sum); 120 | } 121 | 122 | static void insertionSort(double* a, int len) { 123 | int i, j; 124 | double tmp; 125 | for (i = 1; i < len; i++) { 126 | j = i; 127 | while (j > 0 && a[j-1] > a[j]) { 128 | tmp = a[j]; 129 | a[j] = a[j-1]; 130 | a[j-1] = tmp; 131 | j--; 132 | } 133 | } 134 | } 135 | 136 | 137 | // Hopefully more numerically stable. 138 | double reflectCost1(double dt, double dx, double frc, double dif, double gradDif, double x0, double xa, double xb) { 139 | // Store the data that can be used to reconstruct gt. 140 | double mu = (beta*dif*frc + gradDif)*dt; 141 | double var = 2.0*dif*dt; 142 | double alpha = 0.5/var; 143 | 144 | double x1 = x0 + dx; 145 | double gtNumer0 = dx - mu; 146 | // The images move in the direction opposite the primary Gaussian. 147 | double plus = x1 + x0 + mu; 148 | double numer1 = plus - 2.0*xa; 149 | double numer2 = plus - 2.0*xb; 150 | 151 | // Sort the exponents. 152 | double arg[3]; 153 | arg[0] = alpha*gtNumer0*gtNumer0; 154 | arg[1] = alpha*numer1*numer1; 155 | arg[2] = alpha*numer2*numer2; 156 | insertionSort(arg, 3); 157 | 158 | // Now we should be able to handle this to avoid floating-point overflows or underflows. 159 | // arg0 is the smallest, so it dominates the probability. 160 | // The right term is log(1 + something_<=_one + something_<=_one). 161 | double cost = arg[0] - log(1.0 + exp(arg[0]-arg[1]) + exp(arg[0]-arg[2])); 162 | 163 | // Avoid race conditions. 164 | gtNumer = gtNumer0; 165 | gtVar = var; 166 | 167 | return 0.5*log(2.0*M_PI*var) + cost; 168 | } 169 | 170 | 171 | double eventCost(int e) { 172 | // Sum of forceBias and forceSys. 173 | double frc = event[e].var[FB] + force->computeVal(event[e].var[X]); 174 | // The diffusivity and its gradient. 175 | double dif = diffuse->computeVal(event[e].var[X]); 176 | double gradDif = diffuse->computeGrad(event[e].var[X]); 177 | 178 | // Add the cost of this event. 179 | return reflectCost1(event[e].del[T], event[e].del[D], frc, dif, gradDif, event[e].var[D], bound0, bound1); 180 | } 181 | }; 182 | 183 | #endif 184 | -------------------------------------------------------------------------------- /TrajReflect2d.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJREFLECT2D_H 13 | #define TRAJREFLECT2D_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseBicubic.H" 18 | #include "Event.H" 19 | #include "TrajCostComputer.H" 20 | 21 | //#include 22 | 23 | class TrajReflect2d : public TrajCostComputer { 24 | private: 25 | const PiecewiseBicubic* diffuse; 26 | const PiecewiseBicubic* force; 27 | int T, X, Y, D, FB; 28 | int dimension; 29 | double bound0; 30 | double bound1; 31 | 32 | public: 33 | TrajReflect2d(const TrajCostDesc& tcd) : 34 | TrajCostComputer(tcd, 5), dimension(tcd.dimension) { 35 | 36 | if (fieldSel.length() != 2) { 37 | fprintf(stderr, "ERROR trajCost ccg2d takes two fields: (0) diffusivity (1) force \n"); 38 | exit(-1); 39 | } 40 | 41 | if (dimension != 0 && dimension != 1) { 42 | fprintf(stderr, "ERROR trajCost ccg2d: dimension must be 0 or 1 not %d\n", dimension); 43 | exit(-1); 44 | } 45 | 46 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 47 | if (diffuse == NULL) { 48 | fprintf(stderr,"ERROR trajCost ccg2d requires field type bicubic.\n"); 49 | exit(-1); 50 | } 51 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 52 | if (force == NULL) { 53 | fprintf(stderr,"ERROR trajCost ccg2d requires field type bicubic.\n"); 54 | exit(-1); 55 | } 56 | 57 | // Set the boundary based on the diffusivity field and the dimension. 58 | bound0 = diffuse->getBound0(dimension); 59 | bound1 = diffuse->getBound1(dimension); 60 | 61 | T = 2; 62 | X = 0; 63 | Y = 1; 64 | D = 0; 65 | FB = 3; 66 | 67 | updateLocal(); 68 | cloneLast(); 69 | } 70 | 71 | // Event variables. 72 | void eventVarShortcuts() { 73 | T = eventIndList[0]; 74 | X = eventIndList[1]; 75 | Y = eventIndList[2]; 76 | D = eventIndList[3]; 77 | FB = eventIndList[4]; 78 | for (int i = 0; i < 5; i++) printf("eventIndList[%d] = %d %s\n", i, eventIndList[i], eventVarName(i).cs()); 79 | } 80 | // Event variables. 81 | String eventVarName(int ind) const { 82 | switch(ind) { 83 | case 0: 84 | return String("time"); 85 | case 1: 86 | return String("posX"); 87 | case 2: 88 | return String("posY"); 89 | case 3: 90 | return String("displacement"); 91 | case 4: 92 | return String("forceBias"); 93 | default: 94 | return String("UNKNOWN"); 95 | } 96 | } 97 | 98 | String fieldName(int ind) const { 99 | switch(ind) { 100 | case 0: 101 | return String("diffusivity"); 102 | case 1: 103 | return String("force"); 104 | default: 105 | return String("UNKNOWN"); 106 | } 107 | } 108 | 109 | // The heart of the method: Eq 2 of Comer , Chipot, Gonzalez. 110 | double reflectCost(double dt, double dx, double frc, double dif, double gradDif, double x0, double xa, double xb) { 111 | // Store the data that can be used to reconstruct gt. 112 | double mu = beta*dif*frc*dt + gradDif*dt; 113 | double var = 2.0*dif*dt; 114 | double alpha = 0.5/var; 115 | 116 | double x1 = x0 + dx; 117 | double gtNumer0 = dx - mu; 118 | double plus = x1 + x0 - mu; 119 | double numer1 = plus - 2.0*xa; 120 | double numer2 = plus + 2.0*xb; 121 | 122 | double sum = exp(-alpha*gtNumer0*gtNumer0); 123 | sum += exp(-alpha*numer1*numer1); 124 | sum += exp(-alpha*numer2*numer2); 125 | 126 | // Avoid race conditions. 127 | gtNumer = gtNumer0; 128 | gtVar = var; 129 | 130 | return 0.5*log(2.0*M_PI*var) - log(sum); 131 | } 132 | 133 | double eventCost(int e) { 134 | // Sum of forceBias and forceSys. 135 | double frc = event[e].var[FB] + force->computeVal(event[e].var[X], event[e].var[Y]); 136 | // The diffusivity and its gradient. 137 | double dif = diffuse->computeVal(event[e].var[X], event[e].var[Y]); 138 | double gradDif = diffuse->computeGrad(dimension, event[e].var[X], event[e].var[Y]); 139 | 140 | // Add the cost of this event. 141 | return reflectCost(event[e].del[T], event[e].del[D], frc, dif, gradDif, event[e].var[D], bound0, bound1); 142 | } 143 | }; 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /TrajSmolCrankBias.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // Author: Jeff Comer 12 | #ifndef TRAJSMOLCRANKBIAS_H 13 | #define TRAJSMOLCRANKBIAS_H 14 | 15 | #include "useful.H" 16 | #include "Field.H" 17 | #include "PiecewiseLinear.H" 18 | #include "PiecewiseCubic.H" 19 | #include "PiecewiseZero.H" 20 | #include "Event.H" 21 | #include "TrajCostComputer.H" 22 | #include "CrankNicholsonSolver.H" 23 | 24 | class TrajSmolCrankBias : public TrajCostComputer { 25 | private: 26 | const Piecewise1d* diffuse; 27 | const Piecewise1d* force; 28 | const Piecewise1d** biasFieldList; 29 | int T, X; 30 | const Piecewise1d* refField; 31 | CrankNicholsonSolver* solver; 32 | double timestep, maxHop; 33 | IndexList all; 34 | 35 | public: 36 | TrajSmolCrankBias(const Field** ppf, IndexList fieldSel0, const Event* event0, int eventNum0, double kt, int leastLocal, const Piecewise1d** biasFieldList0, double timestep0, double maxHop0) : 37 | TrajCostComputer(ppf, fieldSel0, event0, eventNum0, kt, leastLocal, 3), biasFieldList(biasFieldList0), timestep(timestep0), maxHop(maxHop0) { 38 | 39 | if (tcFieldNum != 2) { 40 | fprintf(stderr, "ERROR trajCost smolCrank takes two fields: (0) diffusivity (1) force\n"); 41 | exit(-1); 42 | } 43 | 44 | diffuse = dynamic_cast(fieldList[fieldSel.get(0)]); 45 | if (diffuse == NULL) { 46 | fprintf(stderr,"ERROR trajCost smolCrank requires field type linear or cubic.\n"); 47 | exit(-1); 48 | } 49 | force = dynamic_cast(fieldList[fieldSel.get(1)]); 50 | if (force == NULL) { 51 | fprintf(stderr,"ERROR trajCost smolCrank requires field type linear or cubic.\n"); 52 | exit(-1); 53 | } 54 | 55 | //std::numeric_limits::infinity(); 56 | 57 | T = 1; 58 | X = 0; 59 | 60 | refField = dynamic_cast(leastLocalField); // defined in TrajCostComputer 61 | if (refField == NULL) { 62 | fprintf(stderr,"ERROR trajCost smolCrank requires leastLocalField type linear or cubic.\n"); 63 | exit(-1); 64 | } 65 | 66 | // The solution calculator. 67 | solver = new CrankNicholsonSolver(refField, timestep, 1.0/beta); 68 | for (int i = 0; i < refField->length(); i++) all.add(i); 69 | 70 | updateLocal(); 71 | cloneLast(); 72 | } 73 | 74 | ~TrajSmolCrankBias() { 75 | delete solver; 76 | } 77 | 78 | 79 | void eventVarShortcuts() { 80 | T = eventIndList[0]; 81 | X = eventIndList[1]; 82 | //for (int i = 0; i < 2; i++) printf("eventIndList[%d] = %d\n", i, eventIndList[i]); 83 | } 84 | // Event variables. 85 | String eventVarName(int ind) const { 86 | switch(ind) { 87 | case 0: 88 | return String("time"); 89 | case 1: 90 | return String("pos"); 91 | case 2: 92 | return String("displacement"); 93 | default: 94 | return String("UNKNOWN"); 95 | } 96 | } 97 | 98 | String fieldName(int ind) const { 99 | switch(ind) { 100 | case 0: 101 | return String("diffusivity"); 102 | case 1: 103 | return String("force"); 104 | default: 105 | return String("UNKNOWN"); 106 | } 107 | } 108 | 109 | // Overload neighbors() to give 110 | // a region around the node defined by the user. 111 | virtual IndexList neighbors(int home) const { 112 | IndexList ret; 113 | 114 | if (maxHop >= refField->length()) return all; 115 | 116 | if (refField->getPeriodic()) { 117 | ret.add(home); 118 | for (int i = 1; i < maxHop; i++) { 119 | ret.add(refField->wrapNode(home-i)); 120 | ret.add(refField->wrapNode(home+i)); 121 | } 122 | } else { 123 | int i0 = home-maxHop; 124 | int i1 = home+maxHop; 125 | if (i0 < 0) i0 = 0; 126 | if (i1 >= refField->length()) i1 = refField->length()-1; 127 | for (int i = i0; i <= i1; i++) ret.add(i); 128 | } 129 | return ret; 130 | } 131 | 132 | // Get the cost for an event by using the Smoluchowski solution 133 | // over the diffusivity and force fields. 134 | double eventCost(int e) { 135 | double x0 = event[e].var[X]; 136 | double x1 = x0 + event[e].del[X]; 137 | int node0 = refField->nearestNode(x0); 138 | int node1 = refField->nearestNode(x1); 139 | 140 | if (node0 < 0 || node0 >= refField->length()) return 0.0; 141 | if (node1 < 0 || node1 >= refField->length()) return 0.0; 142 | 143 | // Do the solution from scratch for each event. Expensive! 144 | double solnProb[solver->length()]; 145 | 146 | // Set the initial condition. 147 | solver->init(solnProb, node0); 148 | int steps = int(event[e].del[T]/timestep); 149 | if (steps < 4) { 150 | fprintf(stderr,"ERROR trajCost smolCrank: Smoluchowski solver steps < 4. Reduce -timestep.\n"); 151 | exit(-1); 152 | } 153 | 154 | // Get the bias force field. 155 | const Piecewise1d* bias; 156 | if (event[e].bias >= 0) bias = biasFieldList[event[e].bias]; 157 | else bias = NULL; 158 | 159 | // Solve. 160 | solver->solve(solnProb, steps, diffuse, force, bias); 161 | solver->conserveProb(solnProb); 162 | //double scale = solver->conserveProb(solnProb, refField->length()); 163 | /*if (scale < 1e-6 || scale > 10.0) { 164 | fprintf(stderr,"WARNING trajCost smolCrank: Probability poorly conserved. scale=%g. Increase -biasSmooth or make -timestep or grid size finer.\n", scale); 165 | return -log(0.0); 166 | }*/ 167 | 168 | if (solnProb[node1] == 0.0 || solnProb[node1] == -0.0 || solnProb[node1] != solnProb[node1]) { 169 | fprintf(stderr,"node0 %d x0 %g node %d x1 %g prob %g\n", node0, x0, node1, x1, solnProb[node1]); 170 | fprintf(stderr,"ERROR trajCost smolCrank: Probability of arrival is zero or NaN. Check -timestep.\n"); 171 | return -log(0.0); 172 | } 173 | // We have stored a solution vector for each node. 174 | double cost = -log(solnProb[node1]); 175 | //nanCheck(cost,'e',e,event[e].del[X],solnProb[node1],solnProb[node1],solnProb[node1]); 176 | return cost; 177 | } 178 | }; 179 | 180 | #endif 181 | -------------------------------------------------------------------------------- /TrialMove.H: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | // A struct with all public members for holding a descriptor of a node. 12 | // Author: Jeff Comer 13 | #include "useful.H" 14 | 15 | #ifndef TRIALMOVE_H 16 | #define TRIALMOVE_H 17 | 18 | struct TrialMove { 19 | int fieldId; 20 | int node; 21 | double trialVal, lastVal; 22 | Vector3 pos; 23 | TrialMove() {} 24 | TrialMove(int id, int n, double tv, double lv, Vector3 pos0) : 25 | fieldId(id), node(n), trialVal(tv), lastVal(lv), pos(pos0) { 26 | } 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /brownTown2dPassage.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include "useful.H" 16 | #include "PiecewiseBicubic.H" 17 | #include "RandomGsl.H" 18 | 19 | double reflectPolar(double x, double eps) { 20 | // Handle very long jumps. 21 | if (x < -180.0 + eps) x = -180.0 + eps; 22 | else if (x > 180.0 - eps) x = 180.0 -eps; 23 | 24 | // Reflecting boundary. 25 | if (x < 0) x = -x; 26 | else if (x > 180.0) x = 360.0 - x; 27 | return x; 28 | } 29 | 30 | int main(int argc, char* argv[]) { 31 | if (argc != 13) { 32 | printf("Usage: %s pmfFile diffuseZFile diffuseThFile z0 goalZ th0 dt kT steps outPeriod seed0 outFile\n", argv[0]); 33 | exit(0); 34 | } 35 | const char* outFile = argv[argc-1]; 36 | PiecewiseBicubic pmf(argv[1], false); 37 | PiecewiseBicubic diffuseZ(argv[2], false); 38 | PiecewiseBicubic diffuseTh(argv[3], false); 39 | double z0 = strtod(argv[4],NULL); 40 | double goalZ = strtod(argv[5],NULL); 41 | double th0 = strtod(argv[6],NULL); 42 | double dt = strtod(argv[7],NULL); 43 | double kT = strtod(argv[8],NULL); 44 | long int steps = atol(argv[9]); 45 | long int seed0 = atol(argv[10]); 46 | int outPeriod = atoi(argv[11]); 47 | 48 | printf("PMF `%s' %d nodes\n", argv[1], pmf.length()); 49 | printf("diffuseZ `%s' %d nodes\n", argv[2], diffuseZ.length()); 50 | printf("diffuseTh `%s' %d nodes\n", argv[3], diffuseTh.length()); 51 | printf("z0 %g goalZ %g th0 %g dt %g kT %g steps %ld outPeriod %d\n", z0, goalZ, th0, dt, kT, steps, outPeriod); 52 | 53 | double beta = 1.0/kT; 54 | long seed = (unsigned int)time((time_t *)NULL) + seed0*seed0*seed0; 55 | Random rando(seed); 56 | 57 | // Open the file. 58 | FILE* out = fopen(outFile,"w"); 59 | if (out == NULL) { 60 | printf("ERROR Couldn't open file %s.\n",outFile); 61 | return false; 62 | } 63 | 64 | fprintf(out, "%.15g %.15g %.15g\n", 0.0, z0, th0); 65 | double lastZ = z0; 66 | double lastTh = th0; 67 | double currZ = lastZ; 68 | double currTh = lastTh; 69 | long int s; 70 | for (s = 1; s <= steps; s++) { 71 | double t = dt*s; 72 | 73 | // Adding in the effective force would be double counting, since 74 | // it's in the PMF we get from colvars 75 | 76 | // Calculate force and diffusivity. 77 | double forZ = -pmf.computeGradX(lastZ,lastTh); 78 | double forTh = -pmf.computeGradY(lastZ,lastTh); 79 | double difZ = diffuseZ.computeVal(lastZ,lastTh); 80 | double gradDifZ = diffuseZ.computeGradX(lastZ,lastTh); 81 | double difTh = diffuseTh.computeVal(lastZ,lastTh); 82 | double gradDifTh = diffuseTh.computeGradY(lastZ,lastTh); 83 | 84 | currZ = lastZ + (beta*forZ*difZ + gradDifZ)*dt + sqrt(2.0*difZ*dt)*rando.gaussian(); 85 | double sigTh = sqrt(2.0*difTh*dt); 86 | currTh = lastTh + (beta*forTh*difZ + gradDifTh)*dt + sigTh*rando.gaussian(); 87 | 88 | // Boundary conditions. 89 | currTh = reflectPolar(currTh, sigTh); 90 | currZ = pmf.wrapX(currZ); 91 | 92 | if (s % outPeriod == 0) 93 | fprintf(out, "%.15g %.15g %.15g\n", t, currZ, currTh); 94 | // Prepare for the next iteration. 95 | lastZ = currZ; 96 | lastTh = currTh; 97 | 98 | // Stop if we have reached the goal. 99 | if (goalZ > z0 && currZ > goalZ) break; 100 | else if (goalZ < z0 && currZ < goalZ) break; 101 | } 102 | 103 | if (s <= steps) printf ("Reached goal at t=%g\n", dt*s); 104 | else printf("Did not reach goal.\n"); 105 | 106 | 107 | fclose(out); 108 | 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /ccgCost.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | 16 | // The heart of the method: Eq 2 of Comer, Chipot, Gonzalez. 17 | inline double ccgCost(double dt, double dx, double frc, double dif, double gradDif, double beta) { 18 | // Store the data that can be used to reconstruct gt. 19 | double gtNumer0 = dx - beta*dif*frc*dt - gradDif*dt; 20 | double gtVar0 = 2.0*dif*dt; 21 | // Avoid race conditions. 22 | //gtNumer = gtNumer0; 23 | //gtVar = gtVar0; 24 | 25 | //printf("kT %g dt %g\n", 1.0/beta, dt); 26 | 27 | return 0.5*log(2.0*M_PI*gtVar0) + 0.5*(gtNumer0*gtNumer0)/gtVar0; 28 | } 29 | 30 | int main(int argc, char* argv[]) { 31 | if (argc != 7) { 32 | printf("Usage: %s dt dx frc dif gradDif kT\n", argv[0]); 33 | exit(0); 34 | } 35 | 36 | double dt = strtod(argv[1],NULL); 37 | double dx = strtod(argv[2],NULL); 38 | double frc = strtod(argv[3],NULL); 39 | double dif = strtod(argv[4],NULL); 40 | double gradDif = strtod(argv[5],NULL); 41 | double beta = 1.0/strtod(argv[6],NULL); 42 | 43 | double cost = ccgCost(dt, dx, frc, dif, gradDif, beta); 44 | 45 | printf("%.10g\n", cost); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /cubicIntegrate.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | #include "PiecewiseCubic.H" 16 | 17 | int main(int argc, char* argv[]) { 18 | if (argc != 3) { 19 | printf("Usage: %s inFile outPrefix\n", argv[0]); 20 | exit(0); 21 | } 22 | 23 | PiecewiseCubic field(argv[1], false); 24 | field.writeIntegral(argv[argc-1], -1.0); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /diffusionFusion.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | #include "DiffusionFusion.H" 16 | #include "CommandLineReader.H" 17 | #include 18 | 19 | void printUsage(const char* argv0) { 20 | DiffusionFusion::printUsage(); 21 | printf("\nUsage: %s config_file [-nt numThreads] [-o outputPrefix]\n", argv0); 22 | printf("\n"); 23 | } 24 | 25 | int main(int argc, char* argv[]) { 26 | printf("*****DiffusionFusion*****\n"); 27 | printf("Written by Jeff Comer \n"); 28 | printf("Implementation of a Bayesian inference scheme for calculating position-dependent diffusivities and free-energy landscapes from MD trajectories.\n"); 29 | printf("The approach is described in Comer, Chipot and Gonzalez-Nilo (2013) J. Chem. Theory Comput., 9(2) pp 876-882.\n\n"); 30 | 31 | // Initialize the clock. 32 | double clockInit = omp_get_wtime(); 33 | 34 | // Read the parameters and options. 35 | CommandLineReader cmd(argc, argv); 36 | 37 | if (cmd.getParamNum() != 1) { 38 | printUsage(argv[0]); 39 | fprintf(stderr,"ERROR A configuration file was not specified on the command line.\n"); 40 | exit(-1); 41 | } 42 | 43 | int numThreads = -1; 44 | String outPreCmdLine; 45 | const int optN = cmd.getOptionNum(); 46 | for (int o = 0; o < optN; o++) { 47 | String opt = cmd.getOption(o); 48 | String val = cmd.getOptionValue(o); 49 | if (opt == String("nt")) { 50 | numThreads = atoi(val.cs()); 51 | } else if(opt == "o") { 52 | outPreCmdLine = val; 53 | } else { 54 | fprintf(stderr,"ERROR Unrecognized option `%s'.\n", opt.cs()); 55 | } 56 | } 57 | 58 | 59 | // Get the number of threads if it's specified. 60 | if (numThreads > 0) { 61 | omp_set_num_threads(numThreads); 62 | printf("OMP: Number of OpenMP threads was set to %d.\n", numThreads); 63 | } 64 | #pragma omp parallel 65 | { 66 | printf("Threads: %d\n", omp_get_num_threads()); 67 | } 68 | 69 | // Make the main object. 70 | DiffusionFusion fusion(cmd.getParam(0), outPreCmdLine); 71 | printf("\nDone with initialization of DiffusionFusion object.\n"); 72 | printf("Running...\n"); 73 | fusion.run(); 74 | 75 | // Report the run time. 76 | double runTime = omp_get_wtime() - clockInit; 77 | printf("\nRun time: %.10g s\n", runTime); 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /doCrank.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "useful.H" 19 | #include "PiecewiseZero.H" 20 | #include "PiecewiseCubic.H" 21 | #include "CrankNicholsonSolver.H" 22 | 23 | int main(int argc, char* argv[]) { 24 | if ( argc != 10 ) { 25 | //printf("Usage: %s inFile diffuseFile forceFile biasFile timestep time kT periodic outPeriod outPrefix\n", argv[0]); 26 | printf("Usage: %s inFile diffuseFile forceFile biasFile timestep time kT outPeriod outPrefix\n", argv[0]); 27 | return 0; 28 | } 29 | const char* inFile = argv[1]; 30 | const char* diffuseFile = argv[2]; 31 | const char* forceFile = argv[3]; 32 | const char* biasFile = argv[4]; 33 | double timestep = strtod(argv[5], NULL); 34 | double tim = strtod(argv[6], NULL); 35 | double kT = strtod(argv[7], NULL); 36 | //int periodic = atoi(argv[8]); 37 | int outPeriod = atoi(argv[argc-2]); 38 | const char* outPrefix = argv[argc-1]; 39 | 40 | bool periodic = false; 41 | 42 | // Load the diffusivity and force. 43 | PiecewiseCubic diffuse(diffuseFile, periodic); 44 | PiecewiseCubic force(forceFile, periodic); 45 | PiecewiseCubic bias(biasFile, periodic); 46 | 47 | // Load the solution domain. 48 | PiecewiseZero init(inFile, periodic); 49 | const int n = init.length(); 50 | double* prob = new double[n]; 51 | for (int i = 0; i < n; i++) prob[i] = init.get(i); 52 | 53 | // Prepare to do the finite difference. 54 | int steps = int(ceil(tim/timestep)); 55 | if (steps == 0) { 56 | fprintf(stderr, "No steps!\n"); 57 | exit(-1); 58 | } 59 | if (outPeriod <= 0) outPeriod = steps; 60 | int cycles = steps/outPeriod; 61 | printf("steps %d\n", steps); 62 | printf("cycles %d\n", cycles); 63 | 64 | // The main object. 65 | CrankNicholsonSolver solver(&init, timestep, kT); 66 | 67 | // Initialize the clock. 68 | clock_t clockInit = clock(); 69 | 70 | char outFile[256]; 71 | for (int c = 0; c < cycles; c++) { 72 | // Write the output. 73 | init.reset(prob, init.getPeriodic()); 74 | solver.conserveProb(init); 75 | snprintf(outFile, 256, "%s.%d.dat", outPrefix, c); 76 | init.write(outFile); 77 | 78 | solver.solve(prob, outPeriod, &diffuse, &force, &bias); 79 | } 80 | 81 | init.reset(prob, init.getPeriodic()); 82 | solver.conserveProb(init); 83 | snprintf(outFile, 256, "%s.final.dat", outPrefix); 84 | init.write(outFile); 85 | printf("value1 %g\n", prob[n/2]); 86 | 87 | printf("\nRun time: %.4g s\n", double(clock()-clockInit)/CLOCKS_PER_SEC); 88 | 89 | delete[] prob; 90 | return 0; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /doCrankDirichlet.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "useful.H" 19 | #include "PiecewiseZero.H" 20 | #include "PiecewiseCubic.H" 21 | #include "CrankNicholsonSolverDirichlet.H" 22 | 23 | void calcCurrent(PiecewiseCubic& curr, const PiecewiseCubic& prob, const PiecewiseCubic& diffuse, const PiecewiseCubic& force, double kT) { 24 | for (int i = 0; i < curr.length(); i++) { 25 | double x = curr.getNodePos(i); 26 | double conc, gradConc; 27 | 28 | prob.computeValGrad(x,conc,gradConc); 29 | double dif = diffuse.computeVal(x); 30 | double frc = force.computeVal(x); 31 | 32 | curr.set(i, -dif*gradConc + frc*dif*conc/kT); 33 | } 34 | } 35 | 36 | void calcResistivity(PiecewiseCubic& resisty, const PiecewiseCubic& prob, const PiecewiseCubic& diffuse, const PiecewiseCubic& force, double kT) { 37 | for (int i = 0; i < resisty.length(); i++) { 38 | double x = resisty.nodePos(i, 0); 39 | double conc, gradConc; 40 | 41 | prob.computeValGrad(x,conc,gradConc); 42 | double dif = diffuse.computeVal(x); 43 | double frc = force.computeVal(x); 44 | 45 | double curr = -dif*gradConc + frc*dif*conc/kT; 46 | resisty.set(i, -gradConc/curr); 47 | } 48 | } 49 | 50 | 51 | int main(int argc, char* argv[]) { 52 | if ( argc != 10 ) { 53 | printf("Usage: %s inFile diffuseFile forceFile timestep time kT perturbation outPeriod outPrefix\n", argv[0]); 54 | return 0; 55 | } 56 | const char* inFile = argv[1]; 57 | const char* diffuseFile = argv[2]; 58 | const char* forceFile = argv[3]; 59 | double timestep = strtod(argv[4], NULL); 60 | double tim = strtod(argv[5], NULL); 61 | double kT = strtod(argv[6], NULL); 62 | double perturbation = strtod(argv[7], NULL); 63 | int outPeriod = atoi(argv[argc-2]); 64 | const char* outPrefix = argv[argc-1]; 65 | 66 | printf("perturbation %g\n", perturbation); 67 | 68 | bool periodic = false; 69 | 70 | // Load the diffusivity and force. 71 | PiecewiseCubic diffuse(diffuseFile, periodic); 72 | PiecewiseCubic force(forceFile, periodic); 73 | 74 | // Load the solution domain. 75 | PiecewiseCubic init(inFile, periodic); 76 | const int n = init.length(); 77 | double* prob = new double[n]; 78 | for (int i = 0; i < n; i++) prob[i] = init.get(i); 79 | // For storing the current. 80 | PiecewiseCubic curr(init); 81 | 82 | // Prepare to do the finite difference. 83 | int steps = int(ceil(tim/timestep)); 84 | if (steps == 0) { 85 | fprintf(stderr, "No steps!\n"); 86 | exit(-1); 87 | } 88 | if (outPeriod <= 0) outPeriod = steps; 89 | int cycles = steps/outPeriod; 90 | printf("steps %d\n", steps); 91 | printf("cycles %d\n", cycles); 92 | 93 | // The main object. 94 | CrankNicholsonSolver solver(&init, timestep, kT, 1.0, 1.0-perturbation); 95 | 96 | // Initialize the clock. 97 | clock_t clockInit = clock(); 98 | 99 | char outFile[256]; 100 | for (int c = 0; c < cycles; c++) { 101 | // Write the output. 102 | init.reset(prob, init.getPeriodic()); 103 | snprintf(outFile, 256, "%s.%d.dat", outPrefix, c); 104 | init.write(outFile); 105 | 106 | snprintf(outFile, 256, "%s.%d.curr", outPrefix, c); 107 | calcCurrent(curr, init, diffuse, force, kT); 108 | curr.write(outFile); 109 | 110 | snprintf(outFile, 256, "%s.%d.resisty", outPrefix, c); 111 | calcResistivity(curr, init, diffuse, force, kT); 112 | curr.write(outFile); 113 | 114 | solver.solve(prob, outPeriod, &diffuse, &force, NULL); 115 | } 116 | 117 | init.reset(prob, init.getPeriodic()); 118 | snprintf(outFile, 256, "%s.final.dat", outPrefix); 119 | init.write(outFile); 120 | printf("value1 %g\n", prob[n/2]); 121 | 122 | printf("\nRun time: %.4g s\n", double(clock()-clockInit)/CLOCKS_PER_SEC); 123 | 124 | delete[] prob; 125 | return 0; 126 | } 127 | 128 | -------------------------------------------------------------------------------- /doFracCrankDirichlet.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "useful.H" 19 | #include "PiecewiseZero.H" 20 | #include "PiecewiseCubic.H" 21 | #include "TimeFracCrankSolverDirichlet.H" 22 | 23 | void calcCurrent(PiecewiseCubic& curr, const PiecewiseCubic& prob, const PiecewiseCubic& diffuse, const PiecewiseCubic& force, double kT) { 24 | for (int i = 0; i < curr.length(); i++) { 25 | double x = curr.nodePos(i, 0); 26 | double conc, gradConc; 27 | 28 | prob.computeValGrad(x,conc,gradConc); 29 | double dif = diffuse.computeVal(x); 30 | double frc = force.computeVal(x); 31 | 32 | curr.set(i, -dif*gradConc + frc*dif*conc/kT); 33 | } 34 | } 35 | 36 | void calcResistivity(PiecewiseCubic& resisty, const PiecewiseCubic& prob, const PiecewiseCubic& diffuse, const PiecewiseCubic& force, double kT) { 37 | for (int i = 0; i < resisty.length(); i++) { 38 | double x = resisty.getNodePos(i); 39 | double conc, gradConc; 40 | 41 | prob.computeValGrad(x,conc,gradConc); 42 | double dif = diffuse.computeVal(x); 43 | double frc = force.computeVal(x); 44 | 45 | double curr = -dif*gradConc + frc*dif*conc/kT; 46 | resisty.set(i, -gradConc/curr); 47 | } 48 | } 49 | 50 | 51 | int main(int argc, char* argv[]) { 52 | if ( argc != 10 ) { 53 | printf("Usage: %s inFile diffuseFile forceFile alphaFile timestep time kT perturbation outPrefix\n", argv[0]); 54 | return 0; 55 | } 56 | const char* inFile = argv[1]; 57 | const char* diffuseFile = argv[2]; 58 | const char* forceFile = argv[3]; 59 | const char* alphaFile = argv[4]; 60 | double timestep = strtod(argv[5], NULL); 61 | double tim = strtod(argv[6], NULL); 62 | double kT = strtod(argv[7], NULL); 63 | double perturbation = strtod(argv[8], NULL); 64 | const char* outPrefix = argv[argc-1]; 65 | 66 | printf("perturbation %g\n", perturbation); 67 | bool periodic = false; 68 | 69 | // Load the diffusivity and force. 70 | PiecewiseCubic diffuse(diffuseFile, periodic); 71 | PiecewiseCubic force(forceFile, periodic); 72 | PiecewiseCubic alpha(alphaFile, periodic); 73 | 74 | // Load the solution domain. 75 | PiecewiseCubic init(inFile, periodic); 76 | const int n = init.length(); 77 | double* prob = new double[n]; 78 | for (int i = 0; i < n; i++) prob[i] = init.get(i); 79 | // For storing the current. 80 | PiecewiseCubic curr(init); 81 | 82 | // Prepare to do the finite difference. 83 | int steps = int(ceil(tim/timestep)); 84 | if (steps == 0) { 85 | fprintf(stderr, "No steps!\n"); 86 | exit(-1); 87 | } 88 | printf("steps %d\n", steps); 89 | 90 | // The main object. 91 | TimeFracCrankSolverDirichlet solver(&init, timestep, kT, 1.0, 1.0-perturbation); 92 | 93 | // Initialize the clock. 94 | clock_t clockInit = clock(); 95 | solver.solve(prob, steps, &diffuse, &force, NULL, &alpha); 96 | 97 | char outFile[256]; 98 | // Write the output. 99 | init.reset(prob, init.getPeriodic()); 100 | snprintf(outFile, 256, "%s.prob", outPrefix); 101 | init.write(outFile); 102 | 103 | snprintf(outFile, 256, "%s.curr", outPrefix); 104 | calcCurrent(curr, init, diffuse, force, kT); 105 | curr.write(outFile); 106 | 107 | snprintf(outFile, 256, "%s.resisty", outPrefix); 108 | calcResistivity(curr, init, diffuse, force, kT); 109 | curr.write(outFile); 110 | printf("value1 %g\n", prob[n/2]); 111 | 112 | printf("\nRun time: %.4g s\n", double(clock()-clockInit)/CLOCKS_PER_SEC); 113 | 114 | delete[] prob; 115 | return 0; 116 | } 117 | 118 | -------------------------------------------------------------------------------- /doHarmonicDiffusion.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | // 14 | // Based on Schulten, "Nonequilibrium Statistical Mechanics" lecture notes, 15 | // eq. 4.120, 4.121, 4.122 16 | 17 | #include 18 | #include 19 | 20 | #include "useful.H" 21 | #include "PiecewiseZero.H" 22 | #include "PiecewiseCubic.H" 23 | 24 | int main(int argc, char* argv[]) { 25 | if ( argc != 8 ) { 26 | printf("Usage: %s inFile diffuse spring time beta x0 outFile\n", argv[0]); 27 | return 0; 28 | } 29 | const char* inFile = argv[1]; 30 | double diffuse = strtod(argv[2], NULL); 31 | double spring = strtod(argv[3], NULL); 32 | double tim = strtod(argv[4], NULL); 33 | double beta = strtod(argv[5], NULL); 34 | double x0 = strtod(argv[6], NULL); 35 | const char* outFile = argv[argc-1]; 36 | 37 | // Load the solution domain. 38 | PiecewiseZero dom(inFile, false); 39 | const int n = dom.length(); 40 | 41 | double tau = 2.0/(beta*spring*diffuse); 42 | double s = 1.0 - exp(-4.0*tim/tau); 43 | double std = sqrt(s/(beta*spring)); 44 | double denom = sqrt(2.0*M_PI)*std; 45 | double mu = x0*exp(-2.0*tim/tau); 46 | 47 | printf("diffuse %g\n", diffuse); 48 | printf("spring %g\n", spring); 49 | printf("time %g\n", tim); 50 | printf("beta %g\n", beta); 51 | printf("x0 %g\n\n", x0); 52 | printf("tau %g\n", tau); 53 | printf("s %g\n", s); 54 | printf("mu %g\n", mu); 55 | printf("std %g\n", std); 56 | 57 | for (int i = 0; i < n; i++) { 58 | double x = dom.getNodePos(i); 59 | double dx = x - mu; 60 | double p = exp(-0.5*dx*dx/(std*std))/denom; 61 | dom.set(i, p); 62 | } 63 | 64 | dom.write(outFile); 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /doSmoluchowski.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | 17 | #include "useful.H" 18 | #include "PiecewiseZero.H" 19 | #include "PiecewiseCubic.H" 20 | 21 | // 5-point numerical derivatives. 22 | double firstDeriv5(double pm2, double pm1, double pc, double pp1, double pp2) { 23 | return (pm2 - 8.0*pm1 + 8.0*pp1 - pp2)/12.0; 24 | } 25 | double secondDeriv5(double pm2, double pm1, double pc, double pp1, double pp2) { 26 | return (-pm2 + 16.0*pm1 - 30.0*pc + 16.0*pp1 - pp2)/12.0; 27 | } 28 | // 3-point numerical derivatives. 29 | double firstDeriv3(double pm1, double pc, double pp1) { 30 | return 0.5*(pp1-pm1); 31 | } 32 | double secondDeriv3(double pm1, double pc, double pp1) { 33 | return pm1 - 2.0*pc + pp1; 34 | } 35 | 36 | double slope(double dif, double gradDif, double frc, double gradFrc, double ddpi, double dpi, double pi) { 37 | return dif*ddpi + (gradDif - dif*frc)*dpi - (dif*gradFrc + gradDif*frc)*pi; 38 | } 39 | 40 | 41 | void finiteDif(const PiecewiseZero& p0, PiecewiseZero& p, double* dif, double* gradDif, double* frc, double* gradFrc, double dt, double dx) { 42 | double dx2 = dx*dx; 43 | 44 | // Get the 5-point stencil. 45 | int n = p0.length(); 46 | 47 | // Absorbing boundary conditions at left. 48 | for (int i = 0; i < 2; i++) { 49 | double pm2 = 0.0; 50 | double pi = p0[i]; 51 | double pp1 = p0[i+1]; 52 | double pp2 = p0[i+2]; 53 | double pm1; 54 | if (i == 0) pm1 = 0.0; 55 | else pm1 = p0[i-1]; 56 | 57 | double dpi = firstDeriv5(pm2,pm1,pi,pp1,pp2)/dx; 58 | double ddpi = secondDeriv5(pm2,pm1,pi,pp1,pp2)/dx2; 59 | p.set(i, pi + slope(dif[i],gradDif[i],frc[i],gradFrc[i],ddpi,dpi,pi)*dt); 60 | } 61 | 62 | // Absorbing boundary conditions at right. 63 | for (int i = n-2; i < n; i++) { 64 | double pm2 = p0[i-2]; 65 | double pm1 = p0[i-1]; 66 | double pi = p0[i]; 67 | double pp2 = 0.0; 68 | double pp1; 69 | if (i == n-1) pp1 = 0.0; 70 | else pp1 = p0[i+1]; 71 | 72 | double dpi = firstDeriv5(pm2,pm1,pi,pp1,pp2)/dx; 73 | double ddpi = secondDeriv5(pm2,pm1,pi,pp1,pp2)/dx2; 74 | p.set(i, pi + slope(dif[i],gradDif[i],frc[i],gradFrc[i],ddpi,dpi,pi)*dt); 75 | } 76 | 77 | // The interior. 78 | for (int i = 2; i < n-2; i++) { 79 | double pm2 = p0[i-2]; 80 | double pm1 = p0[i-1]; 81 | double pi = p0[i]; 82 | double pp1 = p0[i+1]; 83 | double pp2 = p0[i+2]; 84 | 85 | // 5-point numerical derivatives. 86 | double dpi = firstDeriv5(pm2,pm1,pi,pp1,pp2)/dx; 87 | double ddpi = secondDeriv5(pm2,pm1,pi,pp1,pp2)/dx2; 88 | p.set(i, pi + slope(dif[i],gradDif[i],frc[i],gradFrc[i],ddpi,dpi,pi)*dt); 89 | } 90 | } 91 | 92 | 93 | void finiteDif0(const PiecewiseZero& p0, PiecewiseZero& p, double* dif, double* gradDif, double* frc, double* gradFrc, double dt, double dx) { 94 | double dx2 = dx*dx; 95 | 96 | // Get the 5-point stencil. 97 | int n = p0.length(); 98 | 99 | // Absorbing boundary conditions at left. 100 | { 101 | int i = 0; 102 | double pm1 = 0.0; 103 | double pi = p0[i]; 104 | double pp1 = p0[i+1]; 105 | 106 | double dpi = firstDeriv3(pm1,pi,pp1)/dx; 107 | double ddpi = secondDeriv3(pm1,pi,pp1)/dx2; 108 | p.set(i, pi + slope(dif[i],gradDif[i],frc[i],gradFrc[i],ddpi,dpi,pi)*dt); 109 | } 110 | 111 | // Absorbing boundary conditions at right. 112 | { 113 | int i = n-1; 114 | double pm1 = p0[i-1]; 115 | double pi = p0[i]; 116 | double pp1 = 0.0; 117 | 118 | double dpi = firstDeriv3(pm1,pi,pp1)/dx; 119 | double ddpi = secondDeriv3(pm1,pi,pp1)/dx2; 120 | p.set(i, pi + slope(dif[i],gradDif[i],frc[i],gradFrc[i],ddpi,dpi,pi)*dt); 121 | } 122 | 123 | // The interior. 124 | for (int i = 2; i < n-2; i++) { 125 | double pm1 = p0[i-1]; 126 | double pi = p0[i]; 127 | double pp1 = p0[i+1]; 128 | 129 | double dpi = firstDeriv3(pm1,pi,pp1)/dx; 130 | double ddpi = secondDeriv3(pm1,pi,pp1)/dx2; 131 | p.set(i, pi + slope(dif[i],gradDif[i],frc[i],gradFrc[i],ddpi,dpi,pi)*dt); 132 | } 133 | } 134 | 135 | int main(int argc, char* argv[]) { 136 | if ( argc != 8 ) { 137 | printf("Usage: %s inFile diffuseFile forceFile dt time beta outFile\n", argv[0]); 138 | return 0; 139 | } 140 | const char* inFile = argv[1]; 141 | const char* diffuseFile = argv[2]; 142 | const char* forceFile = argv[3]; 143 | double dt = strtod(argv[4], NULL); 144 | double tim = strtod(argv[5], NULL); 145 | double beta = strtod(argv[6], NULL); 146 | const char* outFile = argv[argc-1]; 147 | 148 | // Load the diffusivity and force. 149 | PiecewiseCubic diffuse(diffuseFile, false); 150 | PiecewiseCubic force(forceFile, false); 151 | // Load the solution domain. 152 | PiecewiseZero dom0(inFile, false); 153 | PiecewiseZero dom(dom0); 154 | const int n = dom.length(); 155 | double dx = dom.getDr(); 156 | 157 | // Make pointers to the solution domain. 158 | PiecewiseZero* p0 = &dom0; 159 | PiecewiseZero* p = &dom; 160 | 161 | // Prepare to do the finite difference. 162 | int steps = int(ceil(tim/dt)); 163 | 164 | // Make a list of the diffusivity and other values (maybe more efficient). 165 | double* arDif = new double[n]; 166 | double* arGradDif = new double[n]; 167 | double* arFrcBeta = new double[n]; 168 | double* arGradFrcBeta = new double[n]; 169 | for (int i = 0; i < n; i++) { 170 | double x = p->getNodePos(i); 171 | double dif, gradDif; 172 | diffuse.computeValGrad(x, dif, gradDif); 173 | double frc, gradFrc; 174 | force.computeValGrad(x, frc, gradFrc); 175 | 176 | arDif[i] = dif; 177 | arGradDif[i] = gradDif; 178 | arFrcBeta[i] = beta*frc; 179 | arGradFrcBeta[i] = beta*gradFrc; 180 | } 181 | 182 | for (int s = 0; s < steps; s++) { 183 | // Swap the pointers. 184 | PiecewiseZero* tmp = p0; 185 | p0 = p; 186 | p = tmp; 187 | 188 | // finite 189 | finiteDif0(*p0, *p, arDif, arGradDif, arFrcBeta, arGradFrcBeta, dt, dx); 190 | } 191 | 192 | p->write(outFile); 193 | 194 | delete[] arDif; 195 | delete[] arGradDif; 196 | delete[] arFrcBeta; 197 | delete[] arGradFrcBeta; 198 | return 0; 199 | } 200 | 201 | -------------------------------------------------------------------------------- /doSmoluchowskiReflect.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | 17 | #include "useful.H" 18 | #include "PiecewiseZero.H" 19 | #include "PiecewiseCubic.H" 20 | #include "SmoluchowskiSolver.H" 21 | #include 22 | 23 | int main(int argc, char* argv[]) { 24 | if ( argc != 11 ) { 25 | printf("Usage: %s inFile diffuseFile forceFile biasFile timestep time kT periodic outPeriod outPrefix\n", argv[0]); 26 | return 0; 27 | } 28 | const char* inFile = argv[1]; 29 | const char* diffuseFile = argv[2]; 30 | const char* forceFile = argv[3]; 31 | const char* biasFile = argv[4]; 32 | double timestep = strtod(argv[5], NULL); 33 | double tim = strtod(argv[6], NULL); 34 | double kT = strtod(argv[7], NULL); 35 | int periodic = atoi(argv[8]); 36 | int outPeriod = atoi(argv[argc-2]); 37 | const char* outPrefix = argv[argc-1]; 38 | 39 | // Load the diffusivity and force. 40 | PiecewiseCubic diffuse(diffuseFile, periodic); 41 | PiecewiseCubic force(forceFile, periodic); 42 | PiecewiseCubic bias(biasFile, periodic); 43 | 44 | // Load the solution domain. 45 | PiecewiseZero init(inFile, periodic); 46 | const int n = init.length(); 47 | double* prob = new double[n]; 48 | for (int i = 0; i < n; i++) prob[i] = init.get(i); 49 | 50 | #pragma omp parallel 51 | { 52 | printf("Threads: %d\n", omp_get_num_threads()); 53 | } 54 | 55 | // Prepare to do the finite difference. 56 | int steps = int(ceil(tim/timestep)); 57 | int cycles = steps/outPeriod; 58 | printf("steps %d\n", steps); 59 | printf("cycles %d\n", cycles); 60 | 61 | // The main object. 62 | SmoluchowskiSolver solver(&init, timestep, kT); 63 | 64 | // Initialize the clock. 65 | double clockInit = omp_get_wtime(); 66 | 67 | char outFile[256]; 68 | for (int c = 0; c < cycles; c++) { 69 | // Write the output. 70 | init.reset(prob, init.getPeriodic()); 71 | snprintf(outFile, 256, "%s.%d.dat", outPrefix, c); 72 | init.write(outFile); 73 | 74 | solver.solve(prob, outPeriod, &diffuse, &force, &bias); 75 | } 76 | 77 | double runTime = omp_get_wtime() - clockInit; 78 | printf("\nRun time: %.10g s\n", runTime); 79 | 80 | delete[] prob; 81 | return 0; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /doTimeFrac.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | 17 | #include "useful.H" 18 | #include "PiecewiseZero.H" 19 | #include "PiecewiseCubic.H" 20 | #include "TimeFracCrankSolver.H" 21 | 22 | int main(int argc, char* argv[]) { 23 | if ( argc != 10 ) { 24 | printf("Usage: %s inFile diffuseFile forceFile alphaFile timestep time kT outPeriod outPrefix\n", argv[0]); 25 | return 0; 26 | } 27 | const char* inFile = argv[1]; 28 | const char* diffuseFile = argv[2]; 29 | const char* forceFile = argv[3]; 30 | const char* alphaFile = argv[4]; 31 | double timestep = strtod(argv[5], NULL); 32 | double tim = strtod(argv[6], NULL); 33 | double kT = strtod(argv[7], NULL); 34 | //int periodic = atoi(argv[8]); 35 | int outPeriod = atoi(argv[argc-2]); 36 | const char* outPrefix = argv[argc-1]; 37 | 38 | bool periodic = false; 39 | 40 | // Load the diffusivity and force. 41 | PiecewiseCubic diffuse(diffuseFile, periodic); 42 | PiecewiseCubic force(forceFile, periodic); 43 | PiecewiseCubic alpha(alphaFile, periodic); 44 | 45 | // Load the solution domain. 46 | PiecewiseZero init(inFile, periodic); 47 | const int n = init.length(); 48 | double* prob = new double[n]; 49 | for (int i = 0; i < n; i++) prob[i] = init.get(i); 50 | 51 | // Prepare to do the finite difference. 52 | int steps = int(ceil(tim/timestep)); 53 | if (outPeriod <= 0) outPeriod = steps; 54 | int cycles = steps/outPeriod; 55 | printf("steps %d\n", steps); 56 | printf("cycles %d\n", cycles); 57 | 58 | // The main object. 59 | TimeFracCrankSolver solver(&init, timestep, kT); 60 | 61 | char outFile[256]; 62 | for (int c = 0; c < cycles; c++) { 63 | // Write the output. 64 | init.reset(prob, init.getPeriodic()); 65 | solver.conserveProb(init); 66 | snprintf(outFile, 256, "%s.%d.dat", outPrefix, c); 67 | init.write(outFile); 68 | 69 | solver.solve(prob, outPeriod, &diffuse, &force, NULL, &alpha); 70 | } 71 | 72 | init.reset(prob, init.getPeriodic()); 73 | solver.conserveProb(init); 74 | snprintf(outFile, 256, "%s.final.dat", outPrefix); 75 | init.write(outFile); 76 | printf("value1 %g\n", prob[n/2]); 77 | 78 | delete[] prob; 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /doTimeFracCrank.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | 17 | #include "useful.H" 18 | #include "PiecewiseZero.H" 19 | #include "PiecewiseCubic.H" 20 | #include "TimeFracCrankSolver.H" 21 | #include 22 | 23 | int main(int argc, char* argv[]) { 24 | if ( argc != 9 ) { 25 | printf("Usage: %s inFile diffuseFile forceFile alphaFile timestep time kT outFile\n", argv[0]); 26 | return 0; 27 | } 28 | const char* inFile = argv[1]; 29 | const char* diffuseFile = argv[2]; 30 | const char* forceFile = argv[3]; 31 | const char* alphaFile = argv[4]; 32 | double timestep = strtod(argv[5], NULL); 33 | double tim = strtod(argv[6], NULL); 34 | double kT = strtod(argv[7], NULL); 35 | const char* outFile = argv[argc-1]; 36 | 37 | printf("\ndoTimeFracCrank\n"); 38 | #pragma omp parallel 39 | { 40 | printf("Threads: %d\n", omp_get_num_threads()); 41 | } 42 | 43 | bool periodic = false; 44 | 45 | // Load the diffusivity and force. 46 | PiecewiseCubic diffuse(diffuseFile, periodic); 47 | PiecewiseCubic force(forceFile, periodic); 48 | PiecewiseCubic alpha(alphaFile, periodic); 49 | 50 | // Load the solution domain. 51 | PiecewiseZero init(inFile, periodic); 52 | const int n = init.length(); 53 | double* prob = new double[n]; 54 | for (int i = 0; i < n; i++) prob[i] = init.get(i); 55 | 56 | // Prepare to do the finite difference. 57 | int steps = int(ceil(tim/timestep)); 58 | if (steps == 0) { 59 | fprintf(stderr, "No steps!\n"); 60 | exit(-1); 61 | } 62 | printf("steps %d\n", steps); 63 | 64 | // The main object. 65 | TimeFracCrankSolver solver(&init, timestep, kT); 66 | 67 | // Initialize the clock. 68 | //clock_t clockInit = clock(); 69 | double clockInit = omp_get_wtime(); 70 | 71 | solver.solve(prob, steps, &diffuse, &force, NULL, &alpha); 72 | init.reset(prob, init.getPeriodic()); 73 | double scale = solver.conserveProb(init); 74 | printf("scale %g\n", scale); 75 | init.write(outFile); 76 | printf("value1 %g\n", prob[n/2]); 77 | 78 | //printf("\nRun time: %.4g s\n", double(clock()-clockInit)/CLOCKS_PER_SEC); 79 | double runTime = omp_get_wtime() - clockInit; 80 | printf("Run time: %.10g s\n", runTime); 81 | 82 | delete[] prob; 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /dxToArray2d.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | #include "PiecewiseBicubic.H" 16 | 17 | int main(int argc, char* argv[]) { 18 | if (argc != 3) { 19 | printf("Usage: %s inDxFile outPrefix\n", argv[0]); 20 | exit(0); 21 | } 22 | 23 | PiecewiseBicubic field(argv[1], false); 24 | field.writeArray(argv[argc-1]); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /dxToGnuplot2d.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | #include "PiecewiseBicubic.H" 16 | 17 | int main(int argc, char* argv[]) { 18 | if (argc != 3) { 19 | printf("Usage: %s inDxFile outFile\n", argv[0]); 20 | exit(0); 21 | } 22 | const char* inFile = argv[1]; 23 | const char* outFile = argv[argc-1]; 24 | 25 | PiecewiseBicubic field(inFile, false); 26 | const double x0 = field.getX0(); 27 | const double dx = field.getDx(); 28 | const int nx = field.getNx(); 29 | const double y0 = field.getY0(); 30 | const double dy = field.getDy(); 31 | const int ny = field.getNy(); 32 | 33 | // Open the file. 34 | FILE* out = fopen(outFile,"w"); 35 | if (out == NULL) { 36 | printf("ERROR Couldn't open file %s.\n",outFile); 37 | return false; 38 | } 39 | 40 | // Write the header. 41 | fprintf(out, "# 2\n"); 42 | fprintf(out, "# %.15g %.15g %d 0\n", x0, dx, nx); 43 | fprintf(out, "# %.15g %.15g %d 0\n\n", y0, dy, ny); 44 | 45 | // Write the data. 46 | for (int ix = 0; ix < nx; ix++) { 47 | for (int iy = 0; iy < ny; iy++) { 48 | double val = field.get(field.index(ix,iy)); 49 | fprintf(out," %.15g %.15g %.15g\n", field.getPosX(ix), field.getPosY(iy), val); 50 | } 51 | // An extra newline between different x values. 52 | fprintf(out,"\n"); 53 | } 54 | fclose(out); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /insertDataDx2d1.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | #include "PiecewiseBicubic.H" 16 | 17 | int countValueLines(const char* fileName) { 18 | FILE* inp = fopen(fileName, "r"); 19 | char line[STRLEN]; 20 | int count = 0; 21 | 22 | while (fgets(line, STRLEN, inp) != NULL) { 23 | // Ignore comments. 24 | int len = strlen(line); 25 | if (line[0] == '#') continue; 26 | if (len < 2) continue; 27 | count++; 28 | } 29 | fclose(inp); 30 | 31 | return count; 32 | } 33 | 34 | int readValueLines(const char* fileName, int column, double* val) { 35 | FILE* inp = fopen(fileName, "r"); 36 | char line[STRLEN]; 37 | int count = 0; 38 | int ln = 0; 39 | 40 | while (fgets(line, STRLEN, inp) != NULL) { 41 | ln++; 42 | // Ignore comments. 43 | if (line[0] == '#') continue; 44 | 45 | String s(line); 46 | // Ignore empty lines. 47 | s = s.trim(); 48 | if (s.length() == 0) continue; 49 | 50 | // Check for the right number of columns. 51 | int tokN = s.tokenCount(); 52 | if (tokN <= column) { 53 | fprintf(stderr, "ERROR line %d of file `%s' has too few columns (%d of %d).\n", ln, fileName, tokN, column); 54 | exit(-1); 55 | } 56 | 57 | // Get the desired line. 58 | String* tokList = new String[tokN]; 59 | s.tokenize(tokList); 60 | 61 | val[count] = strtod(tokList[column], NULL); 62 | count++; 63 | } 64 | fclose(inp); 65 | 66 | return count; 67 | } 68 | 69 | //////////////////////////////////////////////////////////////////////////////// 70 | // Driver 71 | int main(int argc, const char* argv[]) { 72 | if (argc != 4 && argc != 5) { 73 | printf("Usage: %s dataFile [dataColumn] inDxFile outDxFile\n", argv[0]); 74 | exit(0); 75 | } 76 | 77 | const char* dataFile = argv[1]; 78 | const char* dxFile = argv[argc-2]; 79 | const char* outFile = argv[argc-1]; 80 | 81 | // Column from which the data is chosen. 82 | int dataCol = 0; 83 | if (argc == 5) dataCol = atoi(argv[2]); 84 | 85 | PiecewiseBicubic field(dxFile, false); 86 | int fieldN = field.length(); 87 | int dataN = countValueLines(dataFile); 88 | 89 | if (fieldN != dataN) { 90 | fprintf(stderr, "ERROR dx `%s' and file `%s' do not have the same number of elements (%d and %d).\n", dxFile, dataFile, fieldN, dataN); 91 | exit(-1); 92 | } 93 | 94 | double* val = new double[dataN]; 95 | readValueLines(dataFile, dataCol, val); 96 | for (int i = 0; i < dataN; i++) field.set(i,val[i]); 97 | 98 | field.write(outFile); 99 | 100 | return 0; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /mapField.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include "useful.H" 15 | #include "PiecewiseCubic.H" 16 | 17 | int main(int argc, char* argv[]) { 18 | if (argc != 4) { 19 | printf("Usage: %s nodeFile valFile outFile\n", argv[0]); 20 | exit(0); 21 | } 22 | 23 | PiecewiseCubic node(argv[1], false); 24 | PiecewiseCubic val(argv[2], false); 25 | 26 | Field* out = node.map( static_cast(&val) ); 27 | out->write(argv[argc-1]); 28 | delete out; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /testFox1.C: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // Copyright 2014-2016 Jeffrey Comer 3 | // 4 | // This file is part of DiffusionFusion. 5 | // 6 | // DiffusionFusion is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 7 | // 8 | // DiffusionFusion is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 9 | // 10 | // You should have received a copy of the GNU General Public License along with DiffusionFusion. If not, see http://www.gnu.org/licenses/. 11 | /////////////////////////////////////////////////////////////////////// 12 | // Author: Jeff Comer 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | double stretchedExp(double x, double alpha, double sqrtKt, double fx) { 19 | double a1 = 1.0-alpha; 20 | double a2 = 2.0-alpha; 21 | double e = -0.5*a2*pow(0.5*alpha,alpha/a2)*pow(fx,1.0/(1.0-0.5*alpha)); 22 | double res = sqrt(1.0/a2)*pow(2.0/alpha, a1/a2)*pow(fx,-a1/a2)*exp(e); 23 | return 0.5*res/(sqrtKt*sqrt(M_PI)); 24 | } 25 | 26 | double foxW(double x, double alpha, double kAlpha, double t, int iterations) { 27 | double sqrtKt = sqrt(kAlpha*pow(t,alpha)); 28 | double fx = fabs(x)/sqrtKt; 29 | 30 | // Check if we can do the asymptotic instead. 31 | // The 20.0-12.66*alpha is based on empirical calculations 32 | // for getting a difference <1e-9 between the series and the asymptotic 33 | // difference of <1e-6, 12.108-7.55*alpha 34 | if (fx > 12.2 - 7.55*alpha) return stretchedExp(x, alpha, sqrtKt, fx); 35 | 36 | double sum = gsl_sf_gammainv(1.0-0.5*alpha); 37 | int n = 1; 38 | double nFac = 1.0; 39 | double fxToN = 1.0; 40 | while (n < iterations) { 41 | double alt = (n%2==0)?1.0:-1.0; 42 | nFac *= n; 43 | fxToN *= fx; 44 | double term = alt*gsl_sf_gammainv(1.0-0.5*alpha*(n+1))*fxToN/nFac; 45 | sum += term; 46 | n++; 47 | } 48 | 49 | return 0.5*sum/sqrtKt; 50 | } 51 | 52 | 53 | int main(int argc, char* argv[]) { 54 | if ( argc != 7 ) { 55 | printf("Equation 45 & 46 of Metzler\n"); 56 | printf("Usage: %s alpha t x0 x1 iterations outFile\n", argv[0]); 57 | return 0; 58 | } 59 | double alpha = strtod(argv[1], NULL); 60 | double t = strtod(argv[2], NULL); 61 | double x0 = strtod(argv[3], NULL); 62 | double x1 = strtod(argv[4], NULL); 63 | int iterations = atoi(argv[5]); 64 | const char* outFile = argv[argc-1]; 65 | 66 | double dx = 0.01; 67 | double kAlpha = 1.0; 68 | 69 | FILE* out = fopen(outFile,"w"); 70 | if (out == NULL) { 71 | fprintf(stderr,"ERROR Couldn't open file %s.\n",outFile); 72 | return -1; 73 | } 74 | 75 | for (double x = x0; x<= x1; x+=dx) { 76 | double y = foxW(x, alpha, kAlpha, t, iterations); 77 | fprintf(out, "%.15g %.15g\n", x, y); 78 | } 79 | fclose(out); 80 | 81 | return 0; 82 | } 83 | --------------------------------------------------------------------------------