1 /**
2  * @file ctfunc.cpp
3  */
4 
5 // This file is part of Cantera. See License.txt in the top-level directory or
6 // at https://cantera.org/license.txt for license and copyright information.
7 
8 #define CANTERA_USE_INTERNAL
9 #include "cantera/clib/ctfunc.h"
10 
11 #include "cantera/numerics/Func1.h"
12 #include "cantera/thermo/ThermoPhase.h"
13 #include "cantera/base/ctexceptions.h"
14 #include "cantera/base/stringUtils.h"
15 
16 #include "Cabinet.h"
17 
18 using namespace Cantera;
19 using namespace std;
20 
21 typedef Func1 func_t;
22 
23 typedef Cabinet<Func1> FuncCabinet;
24 // Assign storage to the Cabinet<Func1> static member
25 template<> FuncCabinet* FuncCabinet::s_storage = 0;
26 
27 extern "C" {
28 
29     // functions
30 
func_new(int type,size_t n,size_t lenp,const double * params)31     int func_new(int type, size_t n, size_t lenp, const double* params)
32     {
33         try {
34             func_t* r=0;
35             size_t m = lenp;
36             if (type == SinFuncType) {
37                 r = new Sin1(params[0]);
38             } else if (type == CosFuncType) {
39                 r = new Cos1(params[0]);
40             } else if (type == ExpFuncType) {
41                 r = new Exp1(params[0]);
42             } else if (type == PowFuncType) {
43                 if (lenp < 1) {
44                     throw CanteraError("func_new",
45                                        "exponent for pow must be supplied");
46                 }
47                 r = new Pow1(params[0]);
48             } else if (type == ConstFuncType) {
49                 r = new Const1(params[0]);
50             } else if (type == FourierFuncType) {
51                 if (lenp < 2*n + 2) {
52                     throw CanteraError("func_new",
53                                        "not enough Fourier coefficients");
54                 }
55                 r = new Fourier1(n, params[n+1], params[0], params + 1,
56                                  params + n + 2);
57             } else if (type == GaussianFuncType) {
58                 if (lenp < 3) {
59                     throw CanteraError("func_new",
60                                        "not enough Gaussian coefficients");
61                 }
62                 r = new Gaussian(params[0], params[1], params[2]);
63             } else if (type == PolyFuncType) {
64                 if (lenp < n + 1) {
65                     throw CanteraError("func_new",
66                                        "not enough polynomial coefficients");
67                 }
68                 r = new Poly1(n, params);
69             } else if (type == ArrheniusFuncType) {
70                 if (lenp < 3*n) {
71                     throw CanteraError("func_new",
72                                        "not enough Arrhenius coefficients");
73                 }
74                 r = new Arrhenius1(n, params);
75             } else if (type == PeriodicFuncType) {
76                 r = new Periodic1(FuncCabinet::item(n), params[0]);
77             } else if (type == SumFuncType) {
78                 r = &newSumFunction(FuncCabinet::item(n).duplicate(),
79                                     FuncCabinet::item(m).duplicate());
80             } else if (type == DiffFuncType) {
81                 r = &newDiffFunction(FuncCabinet::item(n).duplicate(),
82                                      FuncCabinet::item(m).duplicate());
83             } else if (type == ProdFuncType) {
84                 r = &newProdFunction(FuncCabinet::item(n).duplicate(),
85                                      FuncCabinet::item(m).duplicate());
86             } else if (type == RatioFuncType) {
87                 r = &newRatioFunction(FuncCabinet::item(n).duplicate(),
88                                       FuncCabinet::item(m).duplicate());
89             } else if (type == CompositeFuncType) {
90                 r = &newCompositeFunction(FuncCabinet::item(n).duplicate(),
91                                           FuncCabinet::item(m).duplicate());
92             } else if (type == TimesConstantFuncType) {
93                 r = &newTimesConstFunction(FuncCabinet::item(n).duplicate(), params[0]);
94             } else if (type == PlusConstantFuncType) {
95                 r = &newPlusConstFunction(FuncCabinet::item(n).duplicate(), params[0]);
96             } else {
97                 throw CanteraError("func_new","unknown function type");
98                 r = new Func1();
99             }
100             return FuncCabinet::add(r);
101         } catch (...) {
102             return handleAllExceptions(-1, ERR);
103         }
104     }
105 
func_del(int i)106     int func_del(int i)
107     {
108         try {
109             FuncCabinet::del(i);
110             return 0;
111         } catch (...) {
112             return handleAllExceptions(-1, ERR);
113         }
114     }
115 
ct_clearFunc()116     int ct_clearFunc()
117     {
118         try {
119             FuncCabinet::clear();
120             return 0;
121         } catch (...) {
122             return handleAllExceptions(-1, ERR);
123         }
124     }
125 
func_value(int i,double t)126     double func_value(int i, double t)
127     {
128         try {
129             return FuncCabinet::item(i).eval(t);
130         } catch (...) {
131             return handleAllExceptions(DERR, DERR);
132         }
133     }
134 
func_derivative(int i)135     int func_derivative(int i)
136     {
137         try {
138             func_t* r = 0;
139             r = &FuncCabinet::item(i).derivative();
140             return FuncCabinet::add(r);
141         } catch (...) {
142             return handleAllExceptions(-1, ERR);
143         }
144     }
145 
func_duplicate(int i)146     int func_duplicate(int i)
147     {
148         try {
149             func_t* r = 0;
150             r = &FuncCabinet::item(i).duplicate();
151             return FuncCabinet::add(r);
152         } catch (...) {
153             return handleAllExceptions(-1, ERR);
154         }
155     }
156 
func_write(int i,size_t lennm,const char * arg,char * nm)157     int func_write(int i, size_t lennm, const char* arg, char* nm)
158     {
159         try {
160             copyString(FuncCabinet::item(i).write(arg), nm, lennm);
161             return 0;
162         } catch (...) {
163             return handleAllExceptions(-1, ERR);
164         }
165     }
166 }
167