Changeset 13452
- Timestamp:
- 09/26/12 15:32:42 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/modules/AutodiffDriversx/AutodiffDriversx.cpp
r13446 r13452 2 2 * \brief: compute outputs from the AD mode, using our dependents and independents, and drivers available in Adolc. 3 3 */ 4 4 #include <set> 5 5 #include "../../modules/modules.h" 6 6 #include "../../shared/shared.h" … … 21 21 IssmDouble *axp = NULL; 22 22 double *xp = NULL; 23 int anIndepNum; 23 int anIndepIndex; 24 unsigned int * indepIndices = NULL; 25 int tangentDirNum = 1; // <----------- set this via config 24 26 25 27 … … 35 37 36 38 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 } 37 43 38 44 /*retrieve state variable: */ … … 58 64 anEDF_for_solverx_p->dp_x=xNew<double>(anEDF_for_solverx_p->max_n); 59 65 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); 61 67 anEDF_for_solverx_p->dp_y=xNew<double>(anEDF_for_solverx_p->max_m); 62 68 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:*/ 64 71 anEDF_for_solverx_p->dp_U=xNew<double>(anEDF_for_solverx_p->max_m); 65 72 anEDF_for_solverx_p->dpp_U=xNew<double>(num_dependents,anEDF_for_solverx_p->max_m); … … 68 75 69 76 /* 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); 78 96 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 80 103 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 } 87 135 88 136 /* delete the allocated space for the parameters:*/
Note:
See TracChangeset
for help on using the changeset viewer.