Changeset 13452


Ignore:
Timestamp:
09/26/12 15:32:42 (12 years ago)
Author:
utke
Message:

CHG allow more forward variants to be used (note that jacobian may call reverse though)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/modules/AutodiffDriversx/AutodiffDriversx.cpp

    r13446 r13452  
    22 * \brief: compute outputs from the AD mode,  using our dependents and independents, and drivers available in Adolc.
    33 */
    4 
     4#include <set>
    55#include "../../modules/modules.h"
    66#include "../../shared/shared.h"
     
    2121        IssmDouble *axp                = NULL;
    2222        double     *xp                 = NULL;
    23         int         anIndepNum;
     23        int         anIndepIndex;
     24        unsigned int * indepIndices    = NULL;
     25        int         tangentDirNum = 1;  // <----------- set this via config
    2426
    2527       
     
    3537
    3638                        if(!(num_dependents*num_independents)) return;
     39
     40                        if (tangentDirNum<1 || tangentDirNum>num_independents) {
     41                          _error_("tangentDirNum should be in [1,num_dependents]"); // <------------ fix this error message to relate to config
     42                        }
    3743
    3844                        /*retrieve state variable: */
     
    5864                        anEDF_for_solverx_p->dp_x=xNew<double>(anEDF_for_solverx_p->max_n);
    5965                        anEDF_for_solverx_p->dp_X=xNew<double>(anEDF_for_solverx_p->max_n);
    60                         anEDF_for_solverx_p->dpp_X=xNew<double>(anEDF_for_solverx_p->max_n, num_independents);
     66                        anEDF_for_solverx_p->dpp_X=xNew<double>(anEDF_for_solverx_p->max_n, tangentDirNum);
    6167                        anEDF_for_solverx_p->dp_y=xNew<double>(anEDF_for_solverx_p->max_m);
    6268                        anEDF_for_solverx_p->dp_Y=xNew<double>(anEDF_for_solverx_p->max_m);
    63                         anEDF_for_solverx_p->dpp_Y=xNew<double>(anEDF_for_solverx_p->max_m, num_independents);
     69                        anEDF_for_solverx_p->dpp_Y=xNew<double>(anEDF_for_solverx_p->max_m, tangentDirNum);
     70                        /*allocate the space for the parameters to invoke the reverse methods:*/
    6471                        anEDF_for_solverx_p->dp_U=xNew<double>(anEDF_for_solverx_p->max_m);
    6572                        anEDF_for_solverx_p->dpp_U=xNew<double>(num_dependents,anEDF_for_solverx_p->max_m);
     
    6875
    6976                        /* Call AD driver:*/
    70                         // single direction:
    71                         double *tangentDir=xNewZeroInit<double>(num_independents);
    72                         parameters->FindParam(&anIndepNum,AutodiffFosForwardIndexEnum);
    73                         tangentDir[anIndepNum]=1.0;
    74                         double *theJacVecProduct=xNew<double>(num_dependents);
    75                         double *theOutput=xNew<double>(num_dependents);
    76                         if (fos_forward(1,num_dependents,num_independents, 0, xp, tangentDir, theOutput, theJacVecProduct ))
    77                                 _error_("fos_forward returned non-zero error code");
     77                        if (tangentDirNum==1) {
     78                          // single direction:
     79                          double *tangentDir=xNewZeroInit<double>(num_independents);
     80                          parameters->FindParam(&anIndepIndex,AutodiffFosForwardIndexEnum);
     81                          tangentDir[anIndepIndex]=1.0;
     82                          double *jacTimesTangentDir=xNew<double>(num_dependents);
     83                          double *theOutput=xNew<double>(num_dependents);
     84                          if (fos_forward(1,num_dependents,num_independents, 0, xp, tangentDir, theOutput, jacTimesTangentDir ))
     85                            _error_("fos_forward returned non-zero error code");
     86                          results->AddObject(new GenericExternalResult<IssmPDouble*>(results->Size()+1,AutodiffJacobianEnum,jacTimesTangentDir,num_dependents,1,1,0.0));
     87                          xDelete(theOutput);
     88                          xDelete(jacTimesTangentDir);
     89                          xDelete(tangentDir);
     90                        }
     91                        else {
     92                          // full Jacobian or Jacobian projection:
     93                          double **jacTimesSeed=xNew<double>(num_dependents,tangentDirNum);
     94                          if (tangentDirNum>1 && tangentDirNum<num_dependents) {
     95                            double **seed=xNewZeroInit<double>(num_independents,tangentDirNum);
    7896
    79                         results->AddObject(new GenericExternalResult<IssmPDouble*>(results->Size()+1,AutodiffJacobianEnum,theJacVecProduct,num_dependents,1,1,0.0));
     97                            // <<<<<<< from here <<<<<<<<<<<<
     98                            unsigned int * indepIndices=xNew<unsigned int>(tangentDirNum);
     99                            for(int i =0; i< tangentDirNum;++i) {
     100                              indepIndices[i]=i;
     101                            }
     102                            // <<<<<<<< to here << get this vector of independent indices from the config - should be 0 based and ideally also unsigned
    80103
    81 #if 0
    82                         double **J=xNew<double>(num_dependents,num_independents);
    83                         jacobian(1,num_dependents,num_independents,xp,J);
    84                         results->AddObject(new GenericExternalResult<IssmPDouble*>(results->Size()+1,AutodiffJacobianEnum,*J,num_independents,num_dependents,1,1,0.0));
    85                         xDelete(J);
    86 #endif
     104                            // collect indices in a set to prevent accidental duplicates as long as we don't do compression:
     105                            std::set<unsigned int> anIndexSet;
     106                            for (int i=0; i<tangentDirNum; ++i) {
     107                              // make sure the index is in range
     108                              if (indepIndices[i]>num_independents) {
     109                                _error_("indepIndices values must be in [0,num_independents-1]");
     110                              }
     111                              if (anIndexSet.find(indepIndices[i])!=anIndexSet.end()) {
     112                                _error_("duplicate indepIndices values are not allowed until we implement Jacobian decompression");
     113                              }
     114                              anIndexSet.insert(indepIndices[i]);
     115                              // now populate the seed matrix from the set of independent indices;
     116                              // simple setup with a single 1.0 per column and at most a single 1.0 per row
     117                              seed[indepIndices[i]][i]=1.0;
     118                            }
     119                            double *theOutput=xNew<double>(num_dependents);
     120                            if (fov_forward(1,num_dependents,num_independents, tangentDirNum, xp, seed, theOutput, jacTimesSeed )) {
     121                              _error_("fov_forward returned non-zero error code");
     122                            }
     123                            xDelete(theOutput);
     124                            xDelete(indepIndices);
     125                            xDelete(seed);
     126                          }
     127                          else {
     128                            if (jacobian(1,num_dependents,num_independents,xp,jacTimesSeed)) {
     129                                _error_("jacobian returned non-zero error code");
     130                            }
     131                          }
     132                          results->AddObject(new GenericExternalResult<IssmPDouble*>(results->Size()+1,AutodiffJacobianEnum,*jacTimesSeed,num_dependents*tangentDirNum,1,1,0.0));
     133                          xDelete(jacTimesSeed);
     134                        }
    87135
    88136                        /* delete the allocated space for the parameters:*/
Note: See TracChangeset for help on using the changeset viewer.