source: issm/oecreview/Archive/18296-19100/ISSM-18895-18896.diff

Last change on this file was 19102, checked in by Mathieu Morlighem, 10 years ago

NEW: added 18296-19100

File size: 6.5 KB
  • ../trunk-jpl/src/c/Makefile.am

     
    345345                                        ./cores/WrapperCorePointerFromSolutionEnum.cpp\
    346346                                        ./cores/CorePointerFromSolutionEnum.cpp\
    347347                                        ./cores/ad_core.cpp\
     348                                        ./cores/adgradient_core.cpp\
    348349                                        ./main/EnvironmentInit.cpp\
    349350                                        ./main/EnvironmentFinalize.cpp\
    350351                                        ./analyses/EnumToAnalysis.h\
  • ../trunk-jpl/src/c/cores/adgradient_core.cpp

     
     1/*!\file adgradient_core
     2 * \brief: compute gradient for all scalar depenendents, then sum them up as output. This relies mainly on the fos_reverse
     3 * driver, hence the incapacity to merge this with ad_core.cpp.
     4 */
     5
     6/*Includes: {{{*/
     7#ifdef HAVE_CONFIG_H
     8        #include <config.h>
     9#else
     10#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
     11#endif
     12
     13#include <set>
     14#include "./cores.h"
     15#include "../toolkits/toolkits.h"
     16#include "../classes/classes.h"
     17#include "../shared/shared.h"
     18#include "../modules/modules.h"
     19#include "../solutionsequences/solutionsequences.h"
     20/*}}}*/
     21
     22void adgradient_core(FemModel* femmodel){
     23
     24        /*diverse: */
     25        int     i;
     26        int     dummy;
     27        int     num_dependents=0;
     28        int     num_dependents_old=0;
     29        int     num_independents=0;
     30        bool    isautodiff       = false;
     31        int     aDepIndex=0;
     32        int     my_rank=IssmComm::GetRank();
     33
     34        /*state variables: */
     35        IssmDouble *axp = NULL;
     36        IssmPDouble     *xp  = NULL;
     37
     38        /*intermediary: */
     39        IssmPDouble *aWeightVector=NULL;
     40        IssmPDouble *weightVectorTimesJac=NULL;
     41       
     42        /*output: */
     43        IssmPDouble *totalgradient=NULL;
     44
     45        /*AD mode on?: */
     46        femmodel->parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum);
     47
     48        if(isautodiff){
     49
     50                #ifdef _HAVE_ADOLC_
     51                        if(VerboseAutodiff())_printf0_("   start ad core\n");
     52
     53                        /*First, stop tracing: */
     54                        trace_off();
     55               
     56                        /*retrieve parameters: */
     57                        femmodel->parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
     58                        femmodel->parameters->FindParam(&num_independents,AutodiffNumIndependentsEnum);
     59                       
     60                        /*if no dependents, no point in running a driver: */
     61                        if(!(num_dependents*num_independents)) return;
     62
     63                        /*for adolc to run in parallel, we 0 out on rank~=0. But we still keep track of num_dependents:*/
     64                        num_dependents_old=num_dependents;
     65                        if (my_rank!=0){
     66                                num_dependents=0; num_independents=0;
     67                        }
     68                       
     69                        /*retrieve state variable: */
     70                        femmodel->parameters->FindParam(&axp,&dummy,AutodiffXpEnum);
     71                       
     72                        /* driver argument */
     73                        xp=xNew<double>(num_independents);
     74                        for(i=0;i<num_independents;i++){
     75                                xp[i]=reCast<double,IssmDouble>(axp[i]);
     76                        }
     77
     78                        /*get the EDF pointer:*/
     79                        ext_diff_fct *anEDF_for_solverx_p=xDynamicCast<GenericParam<Adolc_edf> * >(femmodel->parameters->FindParamObject(AdolcParamEnum))->GetParameterValue().myEDF_for_solverx_p;
     80
     81                        /* these are always needed regardless of the interpreter */
     82                        anEDF_for_solverx_p->dp_x=xNew<double>(anEDF_for_solverx_p->max_n);
     83                        anEDF_for_solverx_p->dp_y=xNew<double>(anEDF_for_solverx_p->max_m);
     84
     85                        /* Ok, now we are going to call the fos_reverse in a loop on the index, from 0 to num_dependents, so
     86                         * as to generate num_dependents gradients: */
     87
     88                        /*Initialize outputs: */
     89                        totalgradient=xNewZeroInit<IssmPDouble>(num_independents);
     90                       
     91                        for(aDepIndex=0;aDepIndex<num_dependents_old;aDepIndex++){
     92
     93                                /*initialize direction index in the weights vector: */
     94                                aWeightVector=xNewZeroInit<IssmPDouble>(num_dependents);
     95                                if (my_rank==0) aWeightVector[aDepIndex]=1.0;
     96                               
     97                                /*initialize output gradient: */
     98                                weightVectorTimesJac=xNew<IssmPDouble>(num_independents);
     99
     100                                /*set the forward method function pointer: */
     101                                #ifdef _HAVE_GSL_
     102                                anEDF_for_solverx_p->fos_reverse=EDF_fos_reverse_for_solverx;
     103                                #endif
     104                                #ifdef _HAVE_MUMPS_
     105                                anEDF_for_solverx_p->fos_reverse_iArr=fos_reverse_mumpsSolveEDF;
     106                                #endif
     107
     108                                anEDF_for_solverx_p->dp_U=xNew<IssmPDouble>(anEDF_for_solverx_p->max_m);
     109                                anEDF_for_solverx_p->dp_Z=xNew<IssmPDouble>(anEDF_for_solverx_p->max_n);
     110
     111                                /*call driver: */
     112                                fos_reverse(my_rank,num_dependents,num_independents, aWeightVector, weightVectorTimesJac );
     113
     114                                /*Add to totalgradient: */
     115                                if(my_rank==0)for(i=0;i<num_independents;i++)totalgradient[i]+=weightVectorTimesJac[i];
     116
     117                                /*free resources :*/
     118                                xDelete(weightVectorTimesJac);
     119                                xDelete(aWeightVector);
     120                        }
     121               
     122                        /*add totalgradient to results*/
     123                        femmodel->results->AddObject(new GenericExternalResult<IssmPDouble*>(femmodel->results->Size()+1,AutodiffJacobianEnum,totalgradient,num_independents,1,1,0.0));
     124
     125                        if(VerboseAutodiff())_printf0_("   end ad core\n");
     126                       
     127                        /* delete the allocated space for the parameters and free ressources:{{{*/
     128                        xDelete(anEDF_for_solverx_p->dp_x);
     129                        xDelete(anEDF_for_solverx_p->dp_X);
     130                        xDelete(anEDF_for_solverx_p->dpp_X);
     131                        xDelete(anEDF_for_solverx_p->dp_y);
     132                        xDelete(anEDF_for_solverx_p->dp_Y);
     133                        xDelete(anEDF_for_solverx_p->dpp_Y);
     134                        xDelete(anEDF_for_solverx_p->dp_U);
     135                        xDelete(anEDF_for_solverx_p->dpp_U);
     136                        xDelete(anEDF_for_solverx_p->dp_Z);
     137                        xDelete(anEDF_for_solverx_p->dpp_Z);
     138                        xDelete(xp);
     139                        xDelete(totalgradient);
     140                        xDelete(axp); /*}}}*/
     141                #else
     142                        _error_("Should not be requesting AD drivers when an AD library is not available!");
     143                #endif
     144        }
     145}
  • ../trunk-jpl/src/c/cores/cores.h

     
    4242void transient_core(FemModel* femmodel);
    4343void dakota_core(FemModel* femmodel);
    4444void ad_core(FemModel* femmodel);
     45void adgradient_core(FemModel* femmodel);
    4546void dummy_core(FemModel* femmodel);
    4647void gia_core(FemModel* femmodel);
    4748void damage_core(FemModel* femmodel);
  • ../trunk-jpl/src/c/cores/controlad_core.cpp

     
    215215        _printf0_("f(x) = "<<setw(12)<<setprecision(7)<<*pf<<"  |  ");
    216216       
    217217        /*Compute gradient using AD. Gradient is in the results after the ad_core is called*/
    218         ad_core(femmodel);
     218        adgradient_core(femmodel);
    219219
    220220        if(IssmComm::GetRank()==0){
    221221                IssmPDouble* G_temp=NULL;
Note: See TracBrowser for help on using the repository browser.