ROL
ROL_DiodeCircuit.hpp
Go to the documentation of this file.
1 #ifndef ROL_DIODECIRCUIT_HPP
2 #define ROL_DIODECIRCUIT_HPP
3 
4 #include "ROL_Objective.hpp"
5 #include "ROL_StdVector.hpp"
8 
9 #include <iostream>
10 #include <fstream>
11 #include <string>
12 
19 namespace ROL {
20 namespace ZOO {
21 
33  template<class Real>
34  class Objective_DiodeCircuit : public Objective<Real> {
35 
36  typedef std::vector<Real> vector;
37  typedef Vector<Real> V;
41  typedef typename vector::size_type uint;
42 
43  private:
45  Real Vth_;
47  Teuchos::RCP<std::vector<Real> > Imeas_;
49  Teuchos::RCP<std::vector<Real> > Vsrc_;
51  bool lambertw_;
53  Real noise_;
58 
59  Teuchos::RCP<const vector> getVector( const V& x ) {
60  using Teuchos::dyn_cast; using Teuchos::getConst;
61  try {
62  return dyn_cast<const STDV>(getConst(x)).getVector();
63  }
64  catch (std::exception &e) {
65  try {
66  return dyn_cast<const PSV>(getConst(x)).getVector();
67  }
68  catch (std::exception &e) {
69  return dyn_cast<const DSV>(getConst(x)).getVector();
70  }
71  }
72  }
73 
74  Teuchos::RCP<vector> getVector( V& x ) {
75  using Teuchos::dyn_cast;
76  try {
77  return dyn_cast<STDV>(x).getVector();
78  }
79  catch (std::exception &e) {
80  try {
81  return dyn_cast<PSV>(x).getVector();
82  }
83  catch (std::exception &e) {
84  return dyn_cast<DSV>(x).getVector();
85  }
86  }
87  }
88 
89  public:
90 
98  Objective_DiodeCircuit(Real Vth, Real Vsrc_min, Real Vsrc_max, Real Vsrc_step, Real true_Is, Real true_Rs, bool lambertw, Real noise, bool use_adjoint, int use_hessvec){
99  lambertw_ = lambertw;
100  Vth_ = Vth;
101  use_adjoint_ = use_adjoint;
102  use_hessvec_ = use_hessvec;
103  int n = (Vsrc_max-Vsrc_min)/Vsrc_step + 1;
104  Vsrc_ = Teuchos::rcp(new std::vector<Real>(n,0.0));
105  Imeas_ = Teuchos::rcp(new std::vector<Real>(n,0.0));
106  std::ofstream output ("Measurements.dat");
107  Real left = 0.0; Real right = 1.0;
108  if(lambertw_){
109  // Using Lambert-W function
110  std::cout << "Generating data using Lambert-W function." << std::endl;
111  for(int i=0;i<n;i++){
112  (*Vsrc_)[i] = Vsrc_min+i*Vsrc_step;
113  (*Imeas_)[i] = lambertWCurrent(true_Is,true_Rs,(*Vsrc_)[i]);
114  if(noise>0.0){
115  (*Imeas_)[i] += noise*pow(10,int(log10((*Imeas_)[i])))*(( (Real)rand() / (Real)RAND_MAX ) * (right - left) + left);
116  }
117  // Write generated data into file
118  if(output.is_open()){
119  output << std::setprecision(8) << std::scientific << (*Vsrc_)[i] << " " << (*Imeas_)[i] << "\n";
120  }
121  }
122  }
123  else{
124  // Using Newton's method
125  std::cout << "Generating data using Newton's method." << std::endl;
126  for(int i=0;i<n;i++){
127  (*Vsrc_)[i] = Vsrc_min+i*Vsrc_step;
128  Real I0 = 1.e-12; // initial guess for Newton
129  (*Imeas_)[i] = Newton(I0,Vsrc_min+i*Vsrc_step,true_Is,true_Rs);
130  if(noise>0.0){
131  (*Imeas_)[i] += noise*pow(10,int(log10((*Imeas_)[i])))*(( (Real)rand() / (Real)RAND_MAX ) * (right - left) + left);
132  }
133  // Write generated data into file
134  if(output.is_open()){
135  output << std::setprecision(8) << std::scientific << (*Vsrc_)[i] << " " << (*Imeas_)[i] << "\n";
136  }
137  }
138  }
139 
140  output.close();
141 
142  }
143 
151  Objective_DiodeCircuit(Real Vth, std::ifstream& input_file, bool lambertw, Real noise, bool use_adjoint, int use_hessvec){
152  lambertw_ = lambertw;
153  Vth_ = Vth;
154  use_adjoint_ = use_adjoint;
155  use_hessvec_ = use_hessvec;
156  std::string line;
157  int dim = 0;
158  for(int k=0;std::getline(input_file,line);++k){dim=k;} // count number of lines
159  input_file.clear(); // reset to beginning of file
160  input_file.seekg(0,std::ios::beg);
161  Vsrc_ = Teuchos::rcp(new std::vector<Real>(dim,0.0));
162  Imeas_ = Teuchos::rcp(new std::vector<Real>(dim,0.0));
163  double Vsrc, Imeas;
164  std::cout << "Using input file to generate data." << "\n";
165  for(int i=0;i<dim;i++){
166  input_file >> Vsrc;
167  input_file >> Imeas;
168  (*Vsrc_)[i] = Vsrc;
169  (*Imeas_)[i] = Imeas;
170  }
171  input_file.close();
172 
173  }
174 
176  void set_method(bool lambertw){
177  lambertw_ = lambertw;
178  }
179 
190  Real diode(const Real I, const Real Vsrc, const Real Is, const Real Rs){
191  return I-Is*(exp((Vsrc-I*Rs)/Vth_)-1);
192  }
193 
195  Real diodeI(const Real I, const Real Vsrc, const Real Is, const Real Rs){
196  return 1+Is*exp((Vsrc-I*Rs)/Vth_)*(Rs/Vth_);
197  }
198 
200  Real diodeIs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
201  return 1-exp((Vsrc-I*Rs)/Vth_);
202  }
203 
205  Real diodeRs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
206  return Is*exp((Vsrc-I*Rs)/Vth_)*(I/Vth_);
207  }
208 
210  Real diodeII(const Real I, const Real Vsrc, const Real Is, const Real Rs){
211  return -Is*exp((Vsrc-I*Rs)/Vth_)*(Rs/Vth_)*(Rs/Vth_);
212  }
213 
215  Real diodeIIs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
216  return exp((Vsrc-I*Rs)/Vth_)*(Rs/Vth_);
217  }
218 
220  Real diodeIRs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
221  return (Is/Vth_)*exp((Vsrc-I*Rs)/Vth_)*(1-(I*Rs)/Vth_);
222  }
223 
225  Real diodeIsIs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
226  return 0;
227  }
228 
230  Real diodeIsRs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
231  return exp((Vsrc-I*Rs)/Vth_)*(I/Vth_);
232  }
233 
235  Real diodeRsRs(const Real I, const Real Vsrc, const Real Is, const Real Rs){
236  return -Is*exp((Vsrc-I*Rs)/Vth_)*(I/Vth_)*(I/Vth_);
237  }
238 
246  Real Newton(const Real I, const Real Vsrc, const Real Is, const Real Rs){
247  double EPS = 1.e-16;
248  double TOL = 1.e-13;
249  int MAXIT = 200;
250  Real IN = I;
251  Real fval = diode(IN,Vsrc,Is,Rs);
252  Real dfval = 0.0;
253  Real IN_tmp = 0.0;
254  Real fval_tmp = 0.0;
255  Real alpha = 1.0;
256  for ( int i = 0; i < MAXIT; i++ ) {
257  if ( std::fabs(fval) < TOL ) {
258  // std::cout << "converged with |fval| = " << std::fabs(fval) << " and TOL = " << TOL << "\n";
259  break;
260  }
261  dfval = diodeI(IN,Vsrc,Is,Rs);
262  if( std::fabs(dfval) < EPS ){
263  std::cout << "denominator is too small" << std::endl;
264  break;
265  }
266 
267  alpha = 1.0;
268  IN_tmp = IN - alpha*fval/dfval;
269  fval_tmp = diode(IN_tmp,Vsrc,Is,Rs);
270  while ( std::fabs(fval_tmp) >= (1.0-1.e-4*alpha)*std::fabs(fval) ) {
271  alpha /= 2.0;
272  IN_tmp = IN - alpha*fval/dfval;
273  fval_tmp = diode(IN_tmp,Vsrc,Is,Rs);
274  if ( alpha < std::sqrt(EPS) ) {
275  // std::cout << "Step tolerance met\n";
276  break;
277  }
278  }
279  IN = IN_tmp;
280  fval = fval_tmp;
281  // if ( i == MAXIT-1){
282  // std::cout << "did not converge " << std::fabs(fval) << "\n";
283  // }
284  }
285  return IN;
286  }
287 
319  void lambertw(Real x, Real &w, int &ierr, Real &xi){
320  int i=0, maxit = 10;
321  const Real turnpt = -exp(-1.), c1 = 1.5, c2 = .75;
322  Real r, r2, r3, s, mach_eps, relerr = 1., diff;
323  mach_eps = 2.e-15; // float:2e-7
324  ierr = 0;
325 
326  if( x > c1){
327  w = c2*log(x);
328  xi = log( x/ w) - w;
329  }
330  else{
331  if( x >= 0.0){
332  w = x;
333  if( x == 0. ) return;
334  if( x < (1-c2) ) w = x*(1.-x + c1*x*x);
335  xi = - w;
336  }
337  else{
338  if( x >= turnpt){
339  if( x > -0.2 ){
340  w = x*(1.0-x + c1*x*x);
341  xi = log(1.0-x + c1*x*x) - w;
342  }
343  else{
344  diff = x-turnpt;
345  if( diff < 0.0 ) diff = -diff;
346  w = -1 + sqrt(2.0*exp(1.))*sqrt(x-turnpt);
347  if( diff == 0.0 ) return;
348  xi = log( x/ w) - w;
349  }
350  }
351  else{
352  ierr = 1; // x is not in the domain.
353  w = -1.0;
354  return;
355  }
356  }
357  }
358 
359  while( relerr > mach_eps && i<maxit){
360  r = xi/(w+1.0); //singularity at w=-1
361  r2 = r*r;
362  r3 = r2*r;
363  s = 6.*(w+1.0)*(w+1.0);
364  w = w * ( 1.0 + r + r2/(2.0*( w+1.0)) - (2. * w -1.0)*r3/s );
365  if( w * x < 0.0 ) w = -w;
366  xi = log( x/ w) - w;
367 
368  if( x>1.0 ){
369  relerr = xi / w;
370  }
371  else{
372  relerr = xi;
373  }
374  if(relerr < 0.0 ) relerr = -relerr;
375  ++i;
376  }
377  if( i == maxit ) ierr = 2;
378  }
379 
392  Real lambertWCurrent(Real Is, Real Rs, Real Vsrc){
393  Real arg1 = (Vsrc + Is*Rs)/Vth_;
394  Real evd = exp(arg1);
395  Real lambWArg = Is*Rs*evd/Vth_;
396  Real lambWReturn;
397  int ierr;
398  Real lambWError;
399  lambertw(lambWArg, lambWReturn, ierr, lambWError);
400  if(ierr == 1){std::cout << "LambertW error: argument is not in the domain" << std::endl; return -1.0;}
401  if(ierr == 2){std::cout << "LambertW error: BUG!" << std::endl;}
402  Real Id = -Is+Vth_*(lambWReturn)/Rs;
403  //Real Gd = lambWReturn / ((1 + lambWReturn)*RS);
404  return Id;
405  }
406 
407 
410  using Teuchos::RCP;
411  RCP<vector> Ip = getVector(I);
412  RCP<const vector> Sp = getVector(S);
413 
414  uint n = Ip->size();
415 
416  if(lambertw_){
417  // Using Lambert-W function
418  Real lambval;
419  for(uint i=0;i<n;i++){
420  lambval = lambertWCurrent((*Sp)[0],(*Sp)[1],(*Vsrc_)[i]);
421  (*Ip)[i] = lambval;
422  }
423  }
424  else{
425  // Using Newton's method
426  Real I0 = 1.e-12; // Initial guess for Newton
427  for(uint i=0;i<n;i++){
428  (*Ip)[i] = Newton(I0,(*Vsrc_)[i],(*Sp)[0],(*Sp)[1]);
429  }
430  }
431  }
432 
433 
441  Real value(const Vector<Real> &S, Real &tol){
442  using Teuchos::RCP; using Teuchos::rcp;
443  RCP<const vector> Sp = getVector(S);
444  uint n = Imeas_->size();
445  STDV I( rcp( new vector(n,0.0) ) );
446  RCP<vector> Ip = getVector(I);
447 
448  // Solve state equation
449  solve_circuit(I,S);
450  Real val = 0;
451 
452  for(uint i=0;i<n;i++){
453  val += ((*Ip)[i]-(*Imeas_)[i])*((*Ip)[i]-(*Imeas_)[i]);
454  }
455  return val/2.0;
456  }
457 
465  void solve_adjoint(Vector<Real> &lambda, const Vector<Real> &I, const Vector<Real> &S){
466 
467  using Teuchos::RCP;
468  RCP<vector> lambdap = getVector(lambda);
469  RCP<const vector> Ip = getVector(I);
470  RCP<const vector> Sp = getVector(S);
471 
472  uint n = Ip->size();
473  for(uint i=0;i<n;i++){
474  (*lambdap)[i] = ((*Imeas_)[i]-(*Ip)[i])/diodeI((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1]);
475  }
476  }
477 
486 
487  using Teuchos::RCP;
488  RCP<vector> sensp = getVector(sens);
489  RCP<const vector> Ip = getVector(I);
490  RCP<const vector> Sp = getVector(S);
491 
492  uint n = Ip->size();
493  for(uint i=0;i<n;i++){
494  (*sensp)[i] = -diodeIs((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1])/diodeI((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1]);
495  }
496  }
497 
506 
507  using Teuchos::RCP;
508  RCP<vector> sensp = getVector(sens);
509  RCP<const vector> Ip = getVector(I);
510  RCP<const vector> Sp = getVector(S);
511 
512  uint n = Ip->size();
513  for(uint i=0;i<n;i++){
514  (*sensp)[i] = -diodeRs((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1])/diodeI((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1]);
515  }
516  }
517 
519  void gradient(Vector<Real> &g, const Vector<Real> &S, Real &tol){
520 
521  using Teuchos::RCP; using Teuchos::rcp;
522  RCP<vector> gp = getVector(g);
523  RCP<const vector> Sp = getVector(S);
524 
525  uint n = Imeas_->size();
526 
527  STDV I( rcp( new vector(n,0.0) ) );
528  RCP<vector> Ip = getVector(I);
529 
530  // Solve state equation
531  solve_circuit(I,S);
532 
533  if(use_adjoint_){
534  // Compute the gradient of the reduced objective function using adjoint computation
535  STDV lambda( rcp( new vector(n,0.0) ) );
536  RCP<vector> lambdap = getVector(lambda);
537 
538  // Solve adjoint equation
539  solve_adjoint(lambda,I,S);
540 
541  // Compute gradient
542  (*gp)[0] = 0.0; (*gp)[1] = 0.0;
543  for(uint i=0;i<n;i++){
544  (*gp)[0] += diodeIs((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1])*(*lambdap)[i];
545  (*gp)[1] += diodeRs((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1])*(*lambdap)[i];
546  }
547  }
548  else{
549  // Compute the gradient of the reduced objective function using sensitivities
550  STDV sensIs( rcp( new vector(n,0.0) ) );
551  STDV sensRs( rcp( new vector(n,0.0) ) );
552  // Solve sensitivity equations
553  solve_sensitivity_Is(sensIs,I,S);
554  solve_sensitivity_Rs(sensRs,I,S);
555 
556  RCP<vector> sensIsp = getVector(sensIs);
557  RCP<vector> sensRsp = getVector(sensRs);
558 
559  // Write sensitivities into file
560  std::ofstream output ("Sensitivities.dat");
561  for(uint k=0;k<n;k++){
562  if(output.is_open()){
563  output << std::scientific << (*sensIsp)[k] << " " << (*sensRsp)[k] << "\n";
564  }
565  }
566  output.close();
567  // Compute gradient
568  (*gp)[0] = 0.0; (*gp)[1] = 0.0;
569  for(uint i=0;i<n;i++){
570  (*gp)[0] += ((*Ip)[i]-(*Imeas_)[i])*(*sensIsp)[i];
571  (*gp)[1] += ((*Ip)[i]-(*Imeas_)[i])*(*sensRsp)[i];
572  }
573  }
574  }
575 
576 
577 
585  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &S, Real &tol ){
586 
587  using Teuchos::RCP; using Teuchos::rcp;
588 
589  if(use_hessvec_==0){
590  Objective<Real>::hessVec(hv, v, S, tol);
591  }
592  else if(use_hessvec_==1){
593  RCP<vector> hvp = getVector(hv);
594  RCP<const vector> vp = getVector(v);
595  RCP<const vector> Sp = getVector(S);
596 
597  uint n = Imeas_->size();
598 
599  STDV I( rcp( new vector(n,0.0) ) );
600  RCP<vector> Ip = getVector(I);
601 
602  // Solve state equation
603  solve_circuit(I,S);
604 
605  STDV lambda( rcp( new vector(n,0.0) ) );
606  RCP<vector> lambdap = getVector(lambda);
607 
608  // Solve adjoint equation
609  solve_adjoint(lambda,I,S);
610 
611  STDV w( rcp( new vector(n,0.0) ) );
612  RCP<vector> wp = getVector(w);
613 
614  // Solve state sensitivity equation
615  for(uint i=0;i<n;i++){
616  (*wp)[i] = ( (*vp)[0] * diodeIs( (*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1] ) + (*vp)[1] * diodeRs( (*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1] ) ) / diodeI((*Ip)[i],(*Vsrc_)[i],(*Sp)[0],(*Sp)[1]);
617  }
618 
619  STDV p( rcp( new vector(n,0.0) ) );
620  RCP<vector> pp = getVector(p);
621 
622  // Solve for p
623  for(uint j=0;j<n;j++){
624  (*pp)[j] = ( (*wp)[j] + (*lambdap)[j] * diodeII( (*Ip)[j],(*Vsrc_)[j],(*Sp)[0],(*Sp)[1] ) * (*wp)[j] - (*lambdap)[j] * diodeIIs( (*Ip)[j],(*Vsrc_)[j],(*Sp)[0],(*Sp)[1] ) * (*vp)[0] - (*lambdap)[j] * diodeIRs( (*Ip)[j],(*Vsrc_)[j],(*Sp)[0],(*Sp)[1] ) * (*vp)[1] ) / diodeI( (*Ip)[j],(*Vsrc_)[j],(*Sp)[0],(*Sp)[1] );
625  }
626 
627  // Assemble Hessian-vector product
628  (*hvp)[0] = 0.0;(*hvp)[1] = 0.0;
629  for(uint k=0;k<n;k++){
630  (*hvp)[0] += diodeIs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] ) * (*pp)[k] - (*lambdap)[k] * (*wp)[k] * diodeIIs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] ) + (*lambdap)[k] * (*vp)[0] * diodeIsIs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] ) + (*lambdap)[k] * (*vp)[1] * diodeIsRs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] );
631  (*hvp)[1] += diodeRs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] ) * (*pp)[k] - (*lambdap)[k] * (*wp)[k] * diodeIRs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] ) + (*lambdap)[k] * (*vp)[0] * diodeIsRs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] ) + (*lambdap)[k] * (*vp)[1] * diodeRsRs( (*Ip)[k],(*Vsrc_)[k],(*Sp)[0],(*Sp)[1] );
632  }
633  }
634  else if(use_hessvec_==2){
635  //Gauss-Newton approximation
636  RCP<vector> hvp = getVector(hv);
637  RCP<const vector> vp = getVector(v);
638  RCP<const vector> Sp = getVector(S);
639 
640  uint n = Imeas_->size();
641 
642  STDV I( rcp( new vector(n,0.0) ) );
643  RCP<vector> Ip = getVector(I);
644 
645  // Solve state equation
646  solve_circuit(I,S);
647 
648  // Compute sensitivities
649  STDV sensIs( rcp( new vector(n,0.0) ) );
650  STDV sensRs( rcp( new vector(n,0.0) ) );
651 
652  // Solve sensitivity equations
653  solve_sensitivity_Is(sensIs,I,S);
654  solve_sensitivity_Rs(sensRs,I,S);
655  RCP<vector> sensIsp = getVector(sensIs);
656  RCP<vector> sensRsp = getVector(sensRs);
657 
658  // Compute approximate Hessian
659  Real H11 = 0.0; Real H12 = 0.0; Real H22 = 0.0;
660  for(uint k=0;k<n;k++){
661  H11 += (*sensIsp)[k]*(*sensIsp)[k];
662  H12 += (*sensIsp)[k]*(*sensRsp)[k];
663  H22 += (*sensRsp)[k]*(*sensRsp)[k];
664  }
665 
666  // Compute approximate Hessian-times-vector
667  (*hvp)[0] = H11*(*vp)[0] + H12*(*vp)[1];
668  (*hvp)[1] = H12*(*vp)[0] + H22*(*vp)[1];
669  }
670  else{
671  ROL::Objective<Real>::hessVec( hv, v, S, tol ); // Use parent class function
672  }
673  }
674 
686  void generate_plot(Real Is_lo, Real Is_up, Real Is_step, Real Rs_lo, Real Rs_up, Real Rs_step){
687  Teuchos::RCP<std::vector<double> > S_rcp = Teuchos::rcp(new std::vector<double>(2,0.0) );
688  StdVector<double> S(S_rcp);
689  std::ofstream output ("Objective.dat");
690 
691  Real Is = 0.0;
692  Real Rs = 0.0;
693  Real val = 0.0;
694  Real tol = 1.e-16;
695  int n = (Is_up-Is_lo)/Is_step + 1;
696  int m = (Rs_up-Rs_lo)/Rs_step + 1;
697  for(int i=0;i<n;i++){
698  Is = Is_lo + i*Is_step;
699  for(int j=0;j<m;j++){
700  Rs = Rs_lo + j*Rs_step;
701  (*S_rcp)[0] = Is;
702  (*S_rcp)[1] = Rs;
703  val = value(S,tol);
704  if(output.is_open()){
705  output << std::scientific << Is << " " << Rs << " " << val << "\n";
706  }
707  }
708  }
709  output.close();
710  }
711 
712 
713  }; // class Objective_DiodeCircuit
714 
715 
716  // template<class Real>
717  // void getDiodeCircuit( Teuchos::RCP<Objective<Real> > &obj, Vector<Real> &x0, Vector<Real> &x ) {
718  // // Cast Initial Guess and Solution Vectors
719  // Teuchos::RCP<std::vector<Real> > x0p =
720  // Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<PrimalScaledStdVector<Real> >(x0)).getVector());
721  // Teuchos::RCP<std::vector<Real> > xp =
722  // Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<PrimalScaledStdVector<Real> >(x)).getVector());
723 
724  // int n = xp->size();
725 
726  // // Resize Vectors
727  // n = 2;
728  // x0p->resize(n);
729  // xp->resize(n);
730 
731  // // Instantiate Objective Function
732  // obj = Teuchos::rcp( new Objective_DiodeCircuit<Real> (0.02585,0.0,1.0,1.e-2));
733  // //ROL::Objective_DiodeCircuit<Real> obj(0.02585,0.0,1.0,1.e-2);
734 
735  // // Get Initial Guess
736  // (*x0p)[0] = 1.e-13;
737  // (*x0p)[1] = 0.2;
738 
739  // // Get Solution
740  // (*xp)[0] = 1.e-12;
741  // (*xp)[1] = 0.25;
742 
743  // }
744 
745 
746 } //end namespace ZOO
747 } //end namespace ROL
748 
749 #endif
Provides the interface to evaluate objective functions.
bool use_adjoint_
If true, use adjoint gradient computation, else compute gradient using sensitivities.
Real diodeIsRs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Second derivative of diode equation wrt Is and Rs.
Real noise_
Percentage of noise to add to measurements; if 0.0 - no noise.
Real diodeIsIs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Second derivative of diode equation wrt Is^2.
Objective_DiodeCircuit(Real Vth, std::ifstream &input_file, bool lambertw, Real noise, bool use_adjoint, int use_hessvec)
A constructor using data from given file.
Real lambertWCurrent(Real Is, Real Rs, Real Vsrc)
Find currents using Lambert-W function.
int use_hessvec_
0 - use FD(with scaling), 1 - use exact implementation (with second order derivatives), 2 - use Gauss-Newton approximation (first order derivatives only)
Provides the std::vector implementation of the ROL::Vector interface that handles scalings in the inn...
Teuchos::RCP< vector > getVector(V &x)
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
void solve_sensitivity_Is(Vector< Real > &sens, const Vector< Real > &I, const Vector< Real > &S)
Solve the sensitivity equation wrt Is.
void solve_adjoint(Vector< Real > &lambda, const Vector< Real > &I, const Vector< Real > &S)
Solve the adjoint equation.
void gradient(Vector< Real > &g, const Vector< Real > &S, Real &tol)
Compute the gradient of the reduced objective function either using adjoint or using sensitivities...
Teuchos::RCP< std::vector< Real > > Imeas_
Vector of measured currents in DC analysis (data)
Real Vth_
Thermal voltage (constant)
void generate_plot(Real Is_lo, Real Is_up, Real Is_step, Real Rs_lo, Real Rs_up, Real Rs_step)
Generate data to plot objective function.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:74
Teuchos::RCP< std::vector< Real > > Vsrc_
Vector of source voltages in DC analysis (input)
The diode circuit problem.
Real value(const Vector< Real > &S, Real &tol)
Evaluate objective function.
Real diodeI(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Derivative of diode equation wrt I.
Provides the std::vector implementation of the ROL::Vector interface.
void lambertw(Real x, Real &w, int &ierr, Real &xi)
Lambert-W function for diodes.
Real Newton(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Newton&#39;s method with line search.
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &S, Real &tol)
Compute the Hessian-vector product of the reduced objective function.
void solve_circuit(Vector< Real > &I, const Vector< Real > &S)
Solve circuit given optimization parameters Is and Rs.
Provides the std::vector implementation of the ROL::Vector interface that handles scalings in the inn...
PrimalScaledStdVector< Real > PSV
bool lambertw_
If true, use Lambert-W function to solve circuit, else use Newton&#39;s method.
Real diode(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Diode equation.
Real diodeIs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Derivative of diode equation wrt Is.
Real diodeRsRs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Second derivative of diode equation wrt Rs^2.
Objective_DiodeCircuit(Real Vth, Real Vsrc_min, Real Vsrc_max, Real Vsrc_step, Real true_Is, Real true_Rs, bool lambertw, Real noise, bool use_adjoint, int use_hessvec)
A constructor generating data.
void solve_sensitivity_Rs(Vector< Real > &sens, const Vector< Real > &I, const Vector< Real > &S)
Solve the sensitivity equation wrt Rs.
Real diodeIIs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Second derivative of diode equation wrt I and Is.
Real diodeIRs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Second derivative of diode equation wrt I and Rs.
Real diodeII(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Second derivative of diode equation wrt I^2.
Teuchos::RCP< const vector > getVector(const V &x)
DualScaledStdVector< Real > DSV
Real diodeRs(const Real I, const Real Vsrc, const Real Is, const Real Rs)
Derivative of diode equation wrt Rs.
void set_method(bool lambertw)
Change the method for solving the circuit if needed.