Merge lp:~fluidity-core/fluidity/adjoint into lp:fluidity

Proposed by Patrick Farrell
Status: Merged
Merged at revision: 3521
Proposed branch: lp:~fluidity-core/fluidity/adjoint
Merge into: lp:fluidity
Diff against target: 152406 lines (+52346/-96549)
431 files modified
Makefile.in (+2/-2)
aclocal.m4 (+5/-5)
adjoint/Adjoint_Controls.F90 (+611/-0)
adjoint/Adjoint_Functional_Evaluation.F90 (+108/-28)
adjoint/Adjoint_Global_Variables.F90 (+0/-1)
adjoint/Adjoint_Main_Loop.F90 (+58/-40)
adjoint/Adjoint_Python_Fortran.F90 (+6/-3)
adjoint/Burgers_Adjoint_Callbacks.F90 (+340/-20)
adjoint/Burgers_Control_Callbacks.F90 (+183/-0)
adjoint/Forward_Main_Loop.F90 (+99/-4)
adjoint/Libadjoint_Data_Callbacks.F90 (+23/-0)
adjoint/Makefile.dependencies (+38/-5)
adjoint/Makefile.in (+22/-4)
adjoint/Mangle_Dirichlet_Rows_Module.F90 (+23/-1)
adjoint/Mangle_Options_Tree.F90 (+19/-10)
adjoint/Shallow_Water_Adjoint_Callbacks.F90 (+1/-0)
adjoint/Shallow_Water_Control_Callbacks.F90 (+203/-0)
adjoint/adBuffer.c (+476/-0)
adjoint/adBufferFortran.f (+1848/-0)
adjoint/adStack.c (+683/-0)
adjoint/adStack.h (+75/-0)
adjoint/adjoint_python.c (+14/-2)
adjoint/simple_advection.f90 (+83/-0)
adjoint/simple_advection_b.f90 (+209/-0)
adjoint/simple_advection_d.f90 (+199/-0)
adjoint/tests/test_adj_variables_from_python.F90 (+5/-1)
assemble/Burgers_Assembly.F90 (+84/-0)
assemble/Makefile.dependencies (+16/-9)
assemble/Makefile.in (+1/-1)
assemble/Manifold_Projections.F90 (+3/-1)
configure (+30/-13)
configure.in (+24/-8)
femtools/Makefile.dependencies (+20/-19)
main/Burgers_Equation.F90 (+104/-61)
main/Makefile.dependencies (+26/-23)
main/Shallow_Water.F90 (+26/-7)
main/Simple_Shallow_Water.F90 (+7/-5)
python/fluidity_tools.py (+88/-1)
schemas/adjoint_options.rnc (+54/-1)
schemas/adjoint_options.rng (+79/-0)
schemas/optimality.rnc (+189/-0)
schemas/optimality.rng (+222/-0)
scripts/optimality.py (+720/-0)
tests/burgers_adjoint_bc/Makefile (+0/-5)
tests/burgers_adjoint_bc/adjoint_bc.bml (+0/-213)
tests/burgers_adjoint_bc/burgers_adjoint_bc.xml (+0/-31)
tests/burgers_adjoint_bc/notes_from_colin.tex (+0/-154)
tests/burgers_adjoint_bc/play.py (+0/-67)
tests/burgers_mms_adjoint/Makefile (+0/-10)
tests/burgers_mms_adjoint/burgers.sage (+0/-15)
tests/burgers_mms_adjoint/burgers_mms_adjoint.xml (+0/-69)
tests/burgers_mms_adjoint/mms_A.bml (+0/-231)
tests/burgers_mms_adjoint/mms_A.bound (+0/-4)
tests/burgers_mms_adjoint/mms_A.ele (+0/-102)
tests/burgers_mms_adjoint/mms_A.node (+0/-103)
tests/burgers_mms_adjoint/mms_B.bml (+0/-231)
tests/burgers_mms_adjoint/mms_B.bound (+0/-4)
tests/burgers_mms_adjoint/mms_B.ele (+0/-202)
tests/burgers_mms_adjoint/mms_B.node (+0/-203)
tests/burgers_mms_adjoint/mms_C.bml (+0/-231)
tests/burgers_mms_adjoint/mms_C.bound (+0/-4)
tests/burgers_mms_adjoint/mms_C.ele (+0/-402)
tests/burgers_mms_adjoint/mms_C.node (+0/-403)
tests/burgers_mms_adjoint/mms_D.bml (+0/-231)
tests/burgers_mms_adjoint/mms_D.bound (+0/-4)
tests/burgers_mms_adjoint/mms_D.ele (+0/-802)
tests/burgers_mms_adjoint/mms_D.node (+0/-803)
tests/burgers_mms_adjoint/mms_E.bml (+0/-231)
tests/burgers_mms_adjoint/mms_E.bound (+0/-4)
tests/burgers_mms_adjoint/mms_E.ele (+0/-1602)
tests/burgers_mms_adjoint/mms_E.node (+0/-1603)
tests/burgers_mms_diffusion_adjoint/Makefile (+0/-10)
tests/burgers_mms_diffusion_adjoint/burgers.sage (+0/-22)
tests/burgers_mms_diffusion_adjoint/burgers_mms_diffusion_adjoint.xml (+0/-149)
tests/burgers_mms_diffusion_adjoint/mms_A.bml (+0/-234)
tests/burgers_mms_diffusion_adjoint/mms_A.bound (+0/-4)
tests/burgers_mms_diffusion_adjoint/mms_A.ele (+0/-102)
tests/burgers_mms_diffusion_adjoint/mms_A.node (+0/-103)
tests/burgers_mms_diffusion_adjoint/mms_B.bml (+0/-234)
tests/burgers_mms_diffusion_adjoint/mms_B.bound (+0/-4)
tests/burgers_mms_diffusion_adjoint/mms_B.ele (+0/-202)
tests/burgers_mms_diffusion_adjoint/mms_B.node (+0/-203)
tests/burgers_mms_diffusion_adjoint/mms_C.bml (+0/-234)
tests/burgers_mms_diffusion_adjoint/mms_C.bound (+0/-4)
tests/burgers_mms_diffusion_adjoint/mms_C.ele (+0/-402)
tests/burgers_mms_diffusion_adjoint/mms_C.node (+0/-403)
tests/burgers_mms_diffusion_adjoint/mms_D.bml (+0/-234)
tests/burgers_mms_diffusion_adjoint/mms_D.bound (+0/-4)
tests/burgers_mms_diffusion_adjoint/mms_D.ele (+0/-802)
tests/burgers_mms_diffusion_adjoint/mms_D.node (+0/-803)
tests/burgers_mms_diffusion_adjoint/mms_E.bml (+0/-234)
tests/burgers_mms_diffusion_adjoint/mms_E.bound (+0/-4)
tests/burgers_mms_diffusion_adjoint/mms_E.ele (+0/-1602)
tests/burgers_mms_diffusion_adjoint/mms_E.node (+0/-1603)
tests/burgers_mms_diffusion_replay/Makefile (+15/-0)
tests/burgers_mms_diffusion_replay/burgers.sage (+27/-0)
tests/burgers_mms_diffusion_replay/burgers_mms_diffusion_replay.py (+54/-0)
tests/burgers_mms_diffusion_replay/burgers_mms_diffusion_replay.xml (+25/-0)
tests/burgers_mms_diffusion_replay/mms_A.bml (+200/-0)
tests/burgers_mms_diffusion_replay/mms_A.bound (+4/-0)
tests/burgers_mms_diffusion_replay/mms_A.ele (+102/-0)
tests/burgers_mms_diffusion_replay/mms_A.node (+103/-0)
tests/burgers_mms_diffusion_replay/mms_B.bml (+200/-0)
tests/burgers_mms_diffusion_replay/mms_B.bound (+4/-0)
tests/burgers_mms_diffusion_replay/mms_B.ele (+202/-0)
tests/burgers_mms_diffusion_replay/mms_B.node (+203/-0)
tests/burgers_mms_diffusion_replay/mms_C.bml (+200/-0)
tests/burgers_mms_diffusion_replay/mms_C.bound (+4/-0)
tests/burgers_mms_diffusion_replay/mms_C.ele (+402/-0)
tests/burgers_mms_diffusion_replay/mms_C.node (+403/-0)
tests/burgers_mms_diffusion_replay/mms_D.bml (+200/-0)
tests/burgers_mms_diffusion_replay/mms_D.bound (+4/-0)
tests/burgers_mms_diffusion_replay/mms_D.ele (+802/-0)
tests/burgers_mms_diffusion_replay/mms_D.node (+803/-0)
tests/burgers_mms_diffusion_replay/mms_E.bml (+200/-0)
tests/burgers_mms_diffusion_replay/mms_E.bound (+4/-0)
tests/burgers_mms_diffusion_replay/mms_E.ele (+1602/-0)
tests/burgers_mms_diffusion_replay/mms_E.node (+1603/-0)
tests/burgers_mms_diffusion_time_integral/burgers_mms_diffusion_time_integral.xml (+17/-15)
tests/burgers_mms_diffusion_time_integral/mms_A.bml (+2/-2)
tests/burgers_mms_diffusion_time_integral/mms_B.bml (+2/-2)
tests/burgers_mms_diffusion_time_integral/mms_C.bml (+2/-2)
tests/burgers_mms_diffusion_time_integral/mms_D.bml (+2/-2)
tests/burgers_mms_diffusion_time_integral/mms_E.bml (+2/-2)
tests/burgers_mms_gaussian/burgers_mms_gaussian.xml (+1/-1)
tests/burgers_mms_gaussian_advection/burgers_mms_gaussian_advection.xml (+1/-1)
tests/burgers_mms_replay/Makefile (+15/-0)
tests/burgers_mms_replay/burgers.sage (+27/-0)
tests/burgers_mms_replay/burgers_mms_replay.py (+54/-0)
tests/burgers_mms_replay/burgers_mms_replay.xml (+25/-0)
tests/burgers_mms_replay/mms_A.bml (+204/-0)
tests/burgers_mms_replay/mms_A.bound (+4/-0)
tests/burgers_mms_replay/mms_A.ele (+102/-0)
tests/burgers_mms_replay/mms_A.node (+103/-0)
tests/burgers_mms_replay/mms_B.bml (+204/-0)
tests/burgers_mms_replay/mms_B.bound (+4/-0)
tests/burgers_mms_replay/mms_B.ele (+202/-0)
tests/burgers_mms_replay/mms_B.node (+203/-0)
tests/burgers_mms_replay/mms_C.bml (+204/-0)
tests/burgers_mms_replay/mms_C.bound (+4/-0)
tests/burgers_mms_replay/mms_C.ele (+402/-0)
tests/burgers_mms_replay/mms_C.node (+403/-0)
tests/burgers_mms_replay/mms_D.bml (+204/-0)
tests/burgers_mms_replay/mms_D.bound (+4/-0)
tests/burgers_mms_replay/mms_D.ele (+802/-0)
tests/burgers_mms_replay/mms_D.node (+803/-0)
tests/burgers_mms_replay/mms_E.bml (+204/-0)
tests/burgers_mms_replay/mms_E.bound (+4/-0)
tests/burgers_mms_replay/mms_E.ele (+1602/-0)
tests/burgers_mms_replay/mms_E.node (+1603/-0)
tests/burgers_mms_replay/op_A.oml (+26/-0)
tests/burgers_mms_steady_adjoint_gradient_init/Makefile (+16/-0)
tests/burgers_mms_steady_adjoint_gradient_init/burgers.sage (+11/-0)
tests/burgers_mms_steady_adjoint_gradient_init/burgers_mms_steady_adjoint_gradient_init.xml (+25/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_A.bml (+206/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_A.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_A.ele (+102/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_A.node (+103/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_A_controls.bml (+237/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_B.bml (+206/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_B.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_B.ele (+202/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_B.node (+203/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_C.bml (+206/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_C.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_C.ele (+402/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_C.node (+403/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_D.bml (+206/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_D.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_D.ele (+802/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_D.node (+803/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_E.bml (+209/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_E.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_E.ele (+1602/-0)
tests/burgers_mms_steady_adjoint_gradient_init/mms_E.node (+1603/-0)
tests/burgers_mms_steady_adjoint_gradient_init/op_A.oml (+19/-0)
tests/burgers_mms_steady_adjoint_gradient_init/op_B.oml (+19/-0)
tests/burgers_mms_steady_adjoint_gradient_init/op_C.oml (+19/-0)
tests/burgers_mms_steady_adjoint_gradient_init/op_D.oml (+19/-0)
tests/burgers_mms_steady_adjoint_gradient_init/op_E.oml (+19/-0)
tests/burgers_mms_steady_adjoint_gradient_src/Makefile (+14/-0)
tests/burgers_mms_steady_adjoint_gradient_src/burgers.sage (+11/-0)
tests/burgers_mms_steady_adjoint_gradient_src/burgers_mms_steady_adjoint_gradient_src.xml (+36/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_A.bml (+236/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_A.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_A.ele (+102/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_A.node (+103/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_B.bml (+236/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_B.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_B.ele (+202/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_B.node (+203/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_C.bml (+236/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_C.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_C.ele (+402/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_C.node (+403/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_D.bml (+236/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_D.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_D.ele (+802/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_D.node (+803/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_E.bml (+236/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_E.bound (+4/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_E.ele (+1602/-0)
tests/burgers_mms_steady_adjoint_gradient_src/mms_E.node (+1603/-0)
tests/burgers_mms_steady_adjoint_gradient_src/op_A.oml (+19/-0)
tests/burgers_tadj_mms/Makefile (+0/-10)
tests/burgers_tadj_mms/adjoint_A.mv (+0/-84)
tests/burgers_tadj_mms/adjoint_E.mv (+0/-84)
tests/burgers_tadj_mms/burgers.sage (+0/-17)
tests/burgers_tadj_mms/burgers_A.mv (+0/-84)
tests/burgers_tadj_mms/burgers_tadj_mms.xml (+0/-53)
tests/burgers_tadj_mms/mms_A.bml (+0/-251)
tests/burgers_tadj_mms/mms_A.bound (+0/-4)
tests/burgers_tadj_mms/mms_A.ele (+0/-12)
tests/burgers_tadj_mms/mms_A.node (+0/-13)
tests/burgers_tadj_mms/mms_B.bml (+0/-251)
tests/burgers_tadj_mms/mms_B.bound (+0/-12)
tests/burgers_tadj_mms/mms_B.ele (+0/-606)
tests/burgers_tadj_mms/mms_B.node (+0/-609)
tests/burgers_tadj_mms/mms_C.bml (+0/-251)
tests/burgers_tadj_mms/mms_C.bound (+0/-12)
tests/burgers_tadj_mms/mms_C.ele (+0/-1206)
tests/burgers_tadj_mms/mms_C.node (+0/-1209)
tests/burgers_tadj_mms/mms_D.bml (+0/-251)
tests/burgers_tadj_mms/mms_D.bound (+0/-12)
tests/burgers_tadj_mms/mms_D.ele (+0/-2406)
tests/burgers_tadj_mms/mms_D.node (+0/-2409)
tests/burgers_tadj_mms/mms_E.bml (+0/-251)
tests/burgers_tadj_mms/mms_E.bound (+0/-12)
tests/burgers_tadj_mms/mms_E.ele (+0/-4806)
tests/burgers_tadj_mms/mms_E.node (+0/-4809)
tests/burgers_tadj_nonlin/Makefile (+0/-10)
tests/burgers_tadj_nonlin/burgers.sage (+0/-29)
tests/burgers_tadj_nonlin/burgers_tadj_nonlin.xml (+0/-84)
tests/burgers_tadj_nonlin/mms_A.bml (+0/-321)
tests/burgers_tadj_nonlin/mms_A.bound (+0/-4)
tests/burgers_tadj_nonlin/mms_A.ele (+0/-12)
tests/burgers_tadj_nonlin/mms_A.node (+0/-13)
tests/burgers_tadj_nonlin/mms_B.bml (+0/-321)
tests/burgers_tadj_nonlin/mms_B.bound (+0/-12)
tests/burgers_tadj_nonlin/mms_B.ele (+0/-606)
tests/burgers_tadj_nonlin/mms_B.node (+0/-609)
tests/burgers_tadj_nonlin/mms_C.bml (+0/-321)
tests/burgers_tadj_nonlin/mms_C.bound (+0/-12)
tests/burgers_tadj_nonlin/mms_C.ele (+0/-1206)
tests/burgers_tadj_nonlin/mms_C.node (+0/-1209)
tests/burgers_tadj_nonlin/mms_D.bml (+0/-321)
tests/burgers_tadj_nonlin/mms_D.bound (+0/-12)
tests/burgers_tadj_nonlin/mms_D.ele (+0/-2406)
tests/burgers_tadj_nonlin/mms_D.node (+0/-2409)
tests/burgers_tadj_nonlin/mms_E.bml (+0/-321)
tests/burgers_tadj_nonlin/mms_E.bound (+0/-12)
tests/burgers_tadj_nonlin/mms_E.ele (+0/-4806)
tests/burgers_tadj_nonlin/mms_E.node (+0/-4809)
tests/burgers_tadj_simple/Makefile (+0/-10)
tests/burgers_tadj_simple/burgers.sage (+0/-29)
tests/burgers_tadj_simple/burgers_tadj_simple.xml (+0/-84)
tests/burgers_tadj_simple/mms_A.bml (+0/-335)
tests/burgers_tadj_simple/mms_A.bound (+0/-4)
tests/burgers_tadj_simple/mms_A.ele (+0/-12)
tests/burgers_tadj_simple/mms_A.node (+0/-13)
tests/burgers_tadj_simple/mms_B.bml (+0/-335)
tests/burgers_tadj_simple/mms_B.bound (+0/-12)
tests/burgers_tadj_simple/mms_B.ele (+0/-606)
tests/burgers_tadj_simple/mms_B.node (+0/-609)
tests/burgers_tadj_simple/mms_C.bml (+0/-335)
tests/burgers_tadj_simple/mms_C.bound (+0/-12)
tests/burgers_tadj_simple/mms_C.ele (+0/-1206)
tests/burgers_tadj_simple/mms_C.node (+0/-1209)
tests/burgers_tadj_simple/mms_D.bml (+0/-335)
tests/burgers_tadj_simple/mms_D.bound (+0/-12)
tests/burgers_tadj_simple/mms_D.ele (+0/-2406)
tests/burgers_tadj_simple/mms_D.node (+0/-2409)
tests/burgers_tadj_simple/mms_E.bml (+0/-335)
tests/burgers_tadj_simple/mms_E.bound (+0/-12)
tests/burgers_tadj_simple/mms_E.ele (+0/-4806)
tests/burgers_tadj_simple/mms_E.node (+0/-4809)
tests/burgers_tadj_timestep/Makefile (+0/-10)
tests/burgers_tadj_timestep/burgers.sage (+0/-30)
tests/burgers_tadj_timestep/burgers_tadj_timestep.xml (+0/-84)
tests/burgers_tadj_timestep/mms_A.bml (+0/-333)
tests/burgers_tadj_timestep/mms_A.bound (+0/-4)
tests/burgers_tadj_timestep/mms_A.ele (+0/-12)
tests/burgers_tadj_timestep/mms_A.node (+0/-13)
tests/burgers_tadj_timestep/mms_B.bml (+0/-333)
tests/burgers_tadj_timestep/mms_B.bound (+0/-12)
tests/burgers_tadj_timestep/mms_B.ele (+0/-606)
tests/burgers_tadj_timestep/mms_B.node (+0/-609)
tests/burgers_tadj_timestep/mms_C.bml (+0/-333)
tests/burgers_tadj_timestep/mms_C.bound (+0/-12)
tests/burgers_tadj_timestep/mms_C.ele (+0/-1206)
tests/burgers_tadj_timestep/mms_C.node (+0/-1209)
tests/burgers_tadj_timestep/mms_D.bml (+0/-333)
tests/burgers_tadj_timestep/mms_D.bound (+0/-12)
tests/burgers_tadj_timestep/mms_D.ele (+0/-2406)
tests/burgers_tadj_timestep/mms_D.node (+0/-2409)
tests/burgers_tadj_timestep/mms_E.bml (+0/-333)
tests/burgers_tadj_timestep/mms_E.bound (+0/-12)
tests/burgers_tadj_timestep/mms_E.ele (+0/-4806)
tests/burgers_tadj_timestep/mms_E.node (+0/-4809)
tests/optimality/Makefile (+11/-0)
tests/optimality/dummy.swml (+317/-0)
tests/optimality/optimality.xml (+67/-0)
tests/optimality/optimiser.oml (+68/-0)
tests/optimality/src/Makefile (+2/-0)
tests/optimality/src/mesh_A.bound (+4/-0)
tests/optimality/src/mesh_A.ele (+6/-0)
tests/optimality/src/mesh_A.node (+7/-0)
tests/saltfinger2d_quad/saltfinger2d_quad.xml (+1/-1)
tests/shallow_water_adjoint_default_controls/Makefile (+17/-0)
tests/shallow_water_adjoint_default_controls/adjoint_A.swml (+534/-0)
tests/shallow_water_adjoint_default_controls/adjoint_controls_convergence_rate.py (+54/-0)
tests/shallow_water_adjoint_default_controls/shallow_water_adjoint_default_controls.py (+21/-0)
tests/shallow_water_adjoint_default_controls/shallow_water_adjoint_default_controls.xml (+73/-0)
tests/shallow_water_adjoint_default_controls/source_terms.py (+28/-0)
tests/shallow_water_adjoint_default_controls/source_terms.sage (+25/-0)
tests/shallow_water_adjoint_default_controls/src/Makefile (+6/-0)
tests/shallow_water_adjoint_default_controls_2d/Makefile (+17/-0)
tests/shallow_water_adjoint_default_controls_2d/adjoint_A.swml (+549/-0)
tests/shallow_water_adjoint_default_controls_2d/adjoint_B.swml (+549/-0)
tests/shallow_water_adjoint_default_controls_2d/adjoint_C.swml (+549/-0)
tests/shallow_water_adjoint_default_controls_2d/adjoint_D.swml (+546/-0)
tests/shallow_water_adjoint_default_controls_2d/adjoint_E.swml (+546/-0)
tests/shallow_water_adjoint_default_controls_2d/adjoint_controls_convergence_rate_2d.py (+54/-0)
tests/shallow_water_adjoint_default_controls_2d/shallow_water_adjoint_default_controls_2d.py (+29/-0)
tests/shallow_water_adjoint_default_controls_2d/shallow_water_adjoint_default_controls_2d.xml (+73/-0)
tests/shallow_water_adjoint_default_controls_2d/source_terms.py (+29/-0)
tests/shallow_water_adjoint_default_controls_2d/source_terms.sage (+26/-0)
tests/shallow_water_adjoint_default_controls_2d/src/Makefile (+9/-0)
tests/shallow_water_adjoint_default_controls_2d/src/mesh_A.geo (+15/-0)
tests/shallow_water_adjoint_default_controls_2d/src/mesh_B.geo (+15/-0)
tests/shallow_water_adjoint_default_controls_2d/src/mesh_C.geo (+15/-0)
tests/shallow_water_adjoint_eta/adjoint_A.swml (+16/-14)
tests/shallow_water_adjoint_eta/shallow_water_adjoint_eta.xml (+5/-5)
tests/shallow_water_adjoint_func_eval/shallow_water_adjoint_func_eval.xml (+1/-5)
tests/shallow_water_adjoint_func_eval_2d/shallow_water_adjoint_func_eval_2d.xml (+18/-4)
tests/shallow_water_adjoint_func_eval_2d/src/mesh_A.msh (+71/-71)
tests/shallow_water_adjoint_func_eval_2d/src/mesh_B.msh (+241/-241)
tests/shallow_water_adjoint_func_eval_2d/src/mesh_C.msh (+881/-881)
tests/shallow_water_adjoint_func_eval_2d/time_integral_2d.py (+0/-8)
tests/shallow_water_optimisation/Makefile (+22/-0)
tests/shallow_water_optimisation/adjoint_A.swml (+338/-0)
tests/shallow_water_optimisation/adjoint_B.swml (+388/-0)
tests/shallow_water_optimisation/adjoint_C.swml (+388/-0)
tests/shallow_water_optimisation/adjoint_D.swml (+388/-0)
tests/shallow_water_optimisation/adjoint_E.swml (+388/-0)
tests/shallow_water_optimisation/optimiser_A.oml (+23/-0)
tests/shallow_water_optimisation/shallow_water_optimisation.py (+19/-0)
tests/shallow_water_optimisation/shallow_water_optimisation.xml (+62/-0)
tests/shallow_water_optimisation/source_terms.sage (+25/-0)
tests/shallow_water_optimisation/src/Makefile (+6/-0)
tests/shallow_water_optimisation/src/mesh_A.bound (+4/-0)
tests/shallow_water_optimisation/src/mesh_A.ele (+12/-0)
tests/shallow_water_optimisation/src/mesh_A.node (+13/-0)
tests/shallow_water_optimisation/src/mesh_B.bound (+4/-0)
tests/shallow_water_optimisation/src/mesh_B.ele (+22/-0)
tests/shallow_water_optimisation/src/mesh_B.node (+23/-0)
tests/shallow_water_optimisation/src/mesh_C.bound (+4/-0)
tests/shallow_water_optimisation/src/mesh_C.ele (+42/-0)
tests/shallow_water_optimisation/src/mesh_C.node (+43/-0)
tests/shallow_water_optimisation/src/mesh_D.bound (+4/-0)
tests/shallow_water_optimisation/src/mesh_D.ele (+82/-0)
tests/shallow_water_optimisation/src/mesh_D.node (+83/-0)
tests/shallow_water_optimisation/src/mesh_E.bound (+4/-0)
tests/shallow_water_optimisation/src/mesh_E.ele (+162/-0)
tests/shallow_water_optimisation/src/mesh_E.node (+163/-0)
tests/shallow_water_optimisation_2d/Makefile (+21/-0)
tests/shallow_water_optimisation_2d/adjoint_A.swml (+349/-0)
tests/shallow_water_optimisation_2d/adjoint_B.swml (+398/-0)
tests/shallow_water_optimisation_2d/adjoint_C.swml (+398/-0)
tests/shallow_water_optimisation_2d/adjoint_D.swml (+398/-0)
tests/shallow_water_optimisation_2d/adjoint_E.swml (+398/-0)
tests/shallow_water_optimisation_2d/constants_2d.py (+27/-0)
tests/shallow_water_optimisation_2d/optimiser_A.log (+15/-0)
tests/shallow_water_optimisation_2d/optimiser_A.oml (+20/-0)
tests/shallow_water_optimisation_2d/optimiser_B.oml (+20/-0)
tests/shallow_water_optimisation_2d/optimiser_C.oml (+20/-0)
tests/shallow_water_optimisation_2d/optimiser_D.oml (+20/-0)
tests/shallow_water_optimisation_2d/optimiser_E.oml (+20/-0)
tests/shallow_water_optimisation_2d/shallow_water_optimisation_2d.xml (+62/-0)
tests/shallow_water_optimisation_2d/source_terms.py (+25/-0)
tests/shallow_water_optimisation_2d/source_terms.sage (+22/-0)
tests/shallow_water_optimisation_2d/src/Makefile (+3/-0)
tests/shallow_water_optimisation_2d/src/mesh_A.bound (+4/-0)
tests/shallow_water_optimisation_2d/src/mesh_A.edge (+38/-0)
tests/shallow_water_optimisation_2d/src/mesh_A.ele (+198/-0)
tests/shallow_water_optimisation_2d/src/mesh_A.geo (+15/-0)
tests/shallow_water_optimisation_2d/src/mesh_A.msh (+358/-0)
tests/shallow_water_optimisation_2d/src/mesh_A.node (+119/-0)
tests/shallow_water_optimisation_bounds/Makefile (+19/-0)
tests/shallow_water_optimisation_bounds/adjoint_A.swml (+378/-0)
tests/shallow_water_optimisation_bounds/adjoint_B.swml (+422/-0)
tests/shallow_water_optimisation_bounds/adjoint_C.swml (+422/-0)
tests/shallow_water_optimisation_bounds/adjoint_D.swml (+422/-0)
tests/shallow_water_optimisation_bounds/optimiser_A.oml (+20/-0)
tests/shallow_water_optimisation_bounds/optimiser_B.oml (+20/-0)
tests/shallow_water_optimisation_bounds/optimiser_C.oml (+20/-0)
tests/shallow_water_optimisation_bounds/optimiser_D.oml (+20/-0)
tests/shallow_water_optimisation_bounds/shallow_water_optimisation_bounds.py (+19/-0)
tests/shallow_water_optimisation_bounds/shallow_water_optimisation_bounds.xml (+63/-0)
tests/shallow_water_optimisation_bounds/source_terms.py (+28/-0)
tests/shallow_water_optimisation_bounds/source_terms.sage (+25/-0)
tests/shallow_water_optimisation_bounds/src/Makefile (+5/-0)
tests/shallow_water_optimisation_check_gradient_2d/Makefile (+11/-0)
tests/shallow_water_optimisation_check_gradient_2d/adjoint_A.swml (+350/-0)
tests/shallow_water_optimisation_check_gradient_2d/constants_2d.py (+27/-0)
tests/shallow_water_optimisation_check_gradient_2d/optimiser_A.oml (+26/-0)
tests/shallow_water_optimisation_check_gradient_2d/shallow_water_optimisation_check_gradient_2d.xml (+18/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/Makefile (+3/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/mesh_A.bound (+4/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/mesh_A.edge (+14/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/mesh_A.ele (+24/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/mesh_A.geo (+15/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/mesh_A.msh (+61/-0)
tests/shallow_water_optimisation_check_gradient_2d/src/mesh_A.node (+20/-0)
tests/shallow_water_optimisation_sphere/Makefile (+16/-0)
tests/shallow_water_optimisation_sphere/constants_2d.py (+33/-0)
tests/shallow_water_optimisation_sphere/optimiser_A.oml (+23/-0)
tests/shallow_water_optimisation_sphere/shallow_water_optimisation_sphere.xml (+40/-0)
tests/shallow_water_optimisation_sphere/source_terms.py (+31/-0)
tests/shallow_water_optimisation_sphere/source_terms.sage (+28/-0)
tests/shallow_water_optimisation_sphere/src/Makefile (+7/-0)
tests/shallow_water_optimisation_sphere/src/sphere_A.geo (+42/-0)
tests/shallow_water_optimisation_sphere/src/sphere_B.geo (+42/-0)
tests/shallow_water_optimisation_sphere/src/sphere_C.geo (+42/-0)
tests/shallow_water_optimisation_sphere/sw_fsphere_A.swml (+471/-0)
tests/shallow_water_optimisation_sphere/sw_fsphere_B.swml (+472/-0)
tests/shallow_water_optimisation_sphere/sw_fsphere_C.swml (+472/-0)
tests/sw_fsphere/sw_fsphere.swml (+1/-1)
tests/sw_kelvin_wave/sw_kelvin_wave.xml (+1/-1)
tests/sw_kelvin_wave_xz/sw_kelvin_wave_xz.xml (+1/-1)
tools/testharness.py (+13/-4)
To merge this branch: bzr merge lp:~fluidity-core/fluidity/adjoint
Reviewer Review Type Date Requested Status
David Ham Approve
Review via email: mp+67670@code.launchpad.net

Description of the change

Overview of the major changes:
------------------------------

* The burgers equation adjoint now works, including nonlinear terms (and so their derivatives). The differentiation of the CG discretisation of the advection term is achieved using tapenade.

* The development of a program (scripts/optimality.py) to solve optimisation problems with fluidity/fluidity-like models.

* More (and more rigorous) test cases. The fundamental tool for verifying the discrete adjoint is the derivative test, which is implemented in optimality.py. Suppose you can compute J(m), and have a candidate for grad(J)(m). Then

|| J(m + dm) - J(m) || should converge at O(||dm||), and
|| J(m + dm) - J(m) - grad(J)(m) . dm || should converge at O(||dm||^2).

* Much stronger tools for debugging adjoint model development, including
  - forward replay verification
  - transpose action correctness
  - nonlinear derivative consistency
  - the derivative test in optimality.py

To post a comment you must log in.
lp:~fluidity-core/fluidity/adjoint updated
3589. By Patrick Farrell

Removing shallow_water_mms_sphere: it never worked.

Simon: I checked out the commit which added this, and the
test is broken there. If you want this test, revive it,
fix it, and add it back.

3590. By Patrick Farrell

In the shallow water model, we now write_diagnostics before the timeloop
begins. (Simon: why? It was r3521. Something to do with the optimiser?)
So we have to change the test to look at stat[1] instead of stat[0] so that
it is looking at the same thing.

3591. By Patrick Farrell

Loosen some tolerances slightly, and activate two new assertions that had been
broken

3592. By Patrick Farrell

Try to get some useful information out of this test; it is failing on
the buildbot, but works when I run it by hand (on my workstation,
and on the buildbot builder)

3593. By Patrick Farrell

Implement David's suggestions during the code review.

Revision history for this message
Patrick Farrell (pefarrell) wrote :

For posterity, David's review requests were:

- get rid of the boundary_condition control from the schema -- the code currently doesn't honour it.
- remove the commented-out comparison code in advection_action in the burgers adjoint callbacks
- Makefile targets for ADing simple advection (but I don't think I can do this one)
- Rather than checking if gfortran version is >= 4.5 myself, use the handy env variable $GFORTRAN_4_5_OR_NEWER that David made
- the testharness should filter out long tests, by default
- have the testharness print out the criteria it's using to search for tests.

These were fixed in r3593.

Revision history for this message
Patrick Farrell (pefarrell) wrote :

All tests pass with --with-adjoint=no:

http://buildbot-ocean.ese.ic.ac.uk:8080/builders/x86_64-branch-adjoint-gcc4/builds/8

(Ignore the colour and look at the stdio; the buildbot is interpreting it incorrectly.)

Just waiting on the --with-adjoint=yes case.

Revision history for this message
David Ham (david-ham) :
review: Approve
Revision history for this message
Patrick Farrell (pefarrell) wrote :

The --with-adjoint case also passes:

http://buildbot-ocean.ese.ic.ac.uk:8080/builders/adjoint/builds/9/steps/shell_9/logs/stdio

The only exception is the channel-flow-dg case, which is known broken in the trunk.

Updating diff...

An updated diff will be available in a few minutes. Reload to see the changes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile.in'
--- Makefile.in 2011-06-27 14:01:01 +0000
+++ Makefile.in 2011-07-12 15:56:32 +0000
@@ -424,7 +424,7 @@
424 @echo " CLEAN tests"424 @echo " CLEAN tests"
425 @cd tests; ../tools/testharness.py --clean >/dev/null425 @cd tests; ../tools/testharness.py --clean >/dev/null
426426
427test: fltools bin/@FLUIDITY@ bin/shallow_water serialtest427test: fltools bin/@FLUIDITY@ bin/shallow_water serialtest bin/burgers_equation
428428
429serialtest:429serialtest:
430ifeq (@MBA2D@,yes)430ifeq (@MBA2D@,yes)
@@ -441,7 +441,7 @@
441 endif441 endif
442endif442endif
443443
444mediumtest:444mediumtest: bin/burgers_equation
445 @cd tests; ../tools/testharness.py -l medium $(EXCLUDE_TAGS) -n $(THREADS)445 @cd tests; ../tools/testharness.py -l medium $(EXCLUDE_TAGS) -n $(THREADS)
446446
447mediumzoltantest:447mediumzoltantest:
448448
=== modified file 'aclocal.m4'
--- aclocal.m4 2011-02-01 18:21:13 +0000
+++ aclocal.m4 2011-07-12 15:56:32 +0000
@@ -1030,10 +1030,11 @@
1030 [adjoint="$withval"],1030 [adjoint="$withval"],
1031 [])1031 [])
10321032
1033bakLIBS=$LIBS
1033tmpLIBS=$LIBS1034tmpLIBS=$LIBS
1034tmpCPPFLAGS=$CPPFLAGS1035tmpCPPFLAGS=$CPPFLAGS
1035if test $adjoint != no; then1036if test "$adjoint" != "no"; then
1036 if test $adjoint != yes; then1037 if test "$adjoint" != "yes"; then
1037 adjoint_LIBS_PATH="$adjoint/lib"1038 adjoint_LIBS_PATH="$adjoint/lib"
1038 adjoint_INCLUDES_PATH="$adjoint/include"1039 adjoint_INCLUDES_PATH="$adjoint/include"
1039 # Ensure the comiler finds the library...1040 # Ensure the comiler finds the library...
@@ -1051,10 +1052,9 @@
1051AC_CHECK_LIB(1052AC_CHECK_LIB(
1052 [adjoint],1053 [adjoint],
1053 [adj_register_equation],1054 [adj_register_equation],
1054 [AC_DEFINE(HAVE_ADJOINT,1,[Define if you have libadjoint.])],1055 [AC_DEFINE(HAVE_ADJOINT,1,[Define if you have libadjoint.])HAVE_ADJOINT=yes],
1055 [AC_MSG_ERROR( [Could not link in libadjoint ... exiting] )] )1056 [AC_MSG_WARN( [Could not link in libadjoint ... ] );HAVE_ADJOINT=no;LIBS=$bakLIBS] )
1056# Save variables...1057# Save variables...
1057AC_LANG_RESTORE1058AC_LANG_RESTORE
10581059
1059echo $LIBS
1060])dnl ACX_adjoint1060])dnl ACX_adjoint
10611061
=== added file 'adjoint/Adjoint_Controls.F90'
--- adjoint/Adjoint_Controls.F90 1970-01-01 00:00:00 +0000
+++ adjoint/Adjoint_Controls.F90 2011-07-12 15:56:32 +0000
@@ -0,0 +1,611 @@
1! Copyright (C) 2006 Imperial College London and others.
2!
3! Please see the AUTHORS file in the main source directory for a full list
4! of copyright holders.
5!
6! Prof. C Pain
7! Applied Modelling and Computation Group
8! Department of Earth Science and Engineering
9! Imperial College London
10!
11! amcgsoftware@imperial.ac.uk
12!
13! This library is free software; you can redistribute it and/or
14! modify it under the terms of the GNU Lesser General Public
15! License as published by the Free Software Foundation,
16! version 2.1 of the License.
17!
18! This library is distributed in the hope that it will be useful,
19! but WITHOUT ANY WARRANTY; without even the implied warranty of
20! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21! Lesser General Public License for more details.
22!
23! You should have received a copy of the GNU Lesser General Public
24! License along with this library; if not, write to the Free Software
25! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26! USA
27
28#include "fdebug.h"
29
30module adjoint_controls
31 use fields
32 use global_parameters, only : PYTHON_FUNC_LEN, OPTION_PATH_LEN
33 use boundary_conditions
34 use spud
35 use state_module
36 use python_state
37
38 implicit none
39
40 private
41
42 public :: adjoint_load_controls, adjoint_write_controls, adjoint_write_control_derivatives, allocate_and_insert_control_derivative_fields
43
44 contains
45
46 ! Retrieves the control details from control number control_no in the optin tree. The outputs are:
47 subroutine get_control_details(states, timestep, control_no, control_name, state_id, field_name, field_type, &
48 & active, have_lb, lb_state_id, lb_material_phase_name, lb_field_name, have_ub, &
49 & ub_state_id, ub_material_phase_name, ub_field_name)
50
51 ! Inputs:
52 type(state_type), dimension(:), intent(in) :: states
53 integer, intent(in) :: control_no, timestep ! control_no: The index of the control in the option tree
54 ! timestep: The timestep
55
56 ! Outputs:
57 character(len=OPTION_PATH_LEN), intent(out) :: control_name, field_type, field_name ! control_name: the name of the control
58 ! field_name: the name of the associated field
59 ! field_type: the type of the associated field
60 integer, intent(out) :: state_id ! the state number in which the associated control field exists
61 logical, intent(out) :: active ! false if the control is active in this timestep (e.g. InitialConditions for timesteps >0)
62 logical, intent(out), optional :: have_ub, have_lb
63 integer, intent(out), optional :: lb_state_id, ub_state_id
64 character(len=OPTION_PATH_LEN), intent(out), optional :: lb_material_phase_name, ub_material_phase_name
65 character(len=OPTION_PATH_LEN), intent(out), optional :: ub_field_name, lb_field_name
66
67 integer :: s_idx
68 character(len=OPTION_PATH_LEN) :: control_type, material_phase_name, name
69 type(scalar_field), pointer :: sfield => null(), sfield2 => null()
70 type(vector_field), pointer :: vfield => null(), vfield2 => null()
71 type(tensor_field), pointer :: tfield => null(), tfield2 => null()
72
73 call get_option("/adjoint/controls/control[" // int2str(control_no) //"]/name", control_name)
74 call get_option("/adjoint/controls/control[" // int2str(control_no) //"]/type/name", control_type)
75 call get_option("/adjoint/controls/control[" // int2str(control_no) //"]/type::" // trim(control_type) // "/field_name", name)
76
77 s_idx = scan(trim(name), "::")
78 if (s_idx == 0) then
79 FLExit("The control " // trim(control_name) // " uses an invalid field_name. It should be of the form Materialphase::Field")
80 end if
81 material_phase_name = name(1:s_idx - 1)
82 field_name = name(s_idx + 2:len_trim(name))
83
84 active = .true.
85
86 ! Find state associated with the material phase
87 do state_id = 1, size(states)
88 if (trim(states(state_id)%name) == trim(material_phase_name)) then
89 exit
90 end if
91 end do
92 if (.not. trim(states(state_id)%name) == trim(material_phase_name)) then
93 FLExit("Could not find state " // trim(material_phase_name) // " as specified in control " // trim(control_name) // ".")
94 end if
95
96 select case (trim(control_type))
97 case ("initial_condition")
98 if (timestep > 0) then
99 active = .false.
100 field_type = ''
101 field_name = ''
102 return
103 endif
104 assert(timestep == 0)
105 if (has_scalar_field(states(state_id), field_name)) then
106 field_type = "scalar"
107 elseif (has_vector_field(states(state_id), field_name)) then
108 field_type = "vector"
109 elseif (has_tensor_field(states(state_id), field_name)) then
110 field_type = "tensor"
111 else
112 ewrite(0, *) "The control field " // trim(field_name) // " specified in control " // trim(control_name) // " is not a field in the state."
113 ewrite(0, *) "The current state is: "
114 call print_state(states(state_id))
115 FLExit("Check your control's field settings.")
116 end if
117
118 case ("source_term")
119 if (timestep == 0) then
120 active = .false.
121 field_type = ''
122 field_name = ''
123 return
124 end if
125
126 if (has_scalar_field(states(state_id), field_name)) then
127 field_type = "scalar"
128 elseif (has_vector_field(states(state_id), field_name)) then
129 field_type = "vector"
130 elseif (has_tensor_field(states(state_id), field_name)) then
131 field_type = "tensor"
132 else
133 ewrite(0, *) "The control field " // trim(name) // " specified in control " // trim(control_name) // &
134 & " is not a field in state " // trim(material_phase_name) // "."
135 ewrite(0, *) "The current state is: "
136 call print_state(states(state_id))
137 FLExit("Check your control's field settings.")
138 end if
139
140 case ("boundary_condition")
141 FLAbort("Boundary condition control not implemented yet.")
142 end select
143
144 !!!! Check bounds settings !!!!
145 ! We only execute this when the optional files are present
146 if (.not. present(have_lb) .or. .not. present(have_ub)) then
147 return
148 endif
149
150 have_ub = have_option("/adjoint/controls/control[0]/bounds/upper_bound")
151 have_ub = have_option("/adjoint/controls/control[" // int2str(control_no) //"]/bounds/upper_bound")
152 have_lb = have_option("/adjoint/controls/control[" // int2str(control_no) //"]/bounds/lower_bound")
153
154 ! Find material phase for the lower bound field
155 if (have_lb) then
156 call get_option("/adjoint/controls/control[" // int2str(control_no) //"]/bounds/lower_bound/field_name", name)
157 if (have_lb) then
158 s_idx = scan(trim(name), "::")
159 if (s_idx == 0) then
160 FLExit("The control lower bound for control " // trim(control_name) // " uses an invalid field_name. It should be of the form Materialphase::Field")
161 end if
162 lb_material_phase_name = name(1:s_idx - 1)
163 lb_field_name = name(s_idx + 2:len_trim(name))
164 ! Find state associated with the lower bound material phase
165 do lb_state_id = 1, size(states)
166 if (trim(states(lb_state_id)%name) == trim(lb_material_phase_name)) then
167 exit
168 end if
169 end do
170 if (.not. trim(states(lb_state_id)%name) == trim(lb_material_phase_name)) then
171 FLExit("Could not find state " // trim(lb_material_phase_name) // " as specified in the lower bound of control " // trim(control_name) // ".")
172 end if
173 end if
174 end if
175
176 ! Find material phase for the upper bound field
177 if (have_ub) then
178 call get_option("/adjoint/controls/control[" // int2str(control_no) //"]/bounds/upper_bound/field_name", name)
179 if (have_ub) then
180 s_idx = scan(trim(name), "::")
181 if (s_idx == 0) then
182 FLExit("The control upper bound for control " // trim(control_name) // " uses an invalid field_name. It should be of the form Materialphase::Field")
183 end if
184 ub_material_phase_name = name(1:s_idx - 1)
185 ub_field_name = name(s_idx + 2:len_trim(name))
186 ! Find state associated with the upper bound material phase
187 do ub_state_id = 1, size(states)
188 if (trim(states(ub_state_id)%name) == trim(ub_material_phase_name)) then
189 exit
190 end if
191 end do
192 if (.not. trim(states(ub_state_id)%name) == trim(ub_material_phase_name)) then
193 FLExit("Could not find state " // trim(ub_material_phase_name) // " as specified in the upper bound of control " // trim(control_name) // ".")
194 end if
195 end if
196 end if
197
198 ! Check that the lower/upper bound fields indeed exist and have the same mesh than the control
199 select case (trim(field_type))
200
201 case ("scalar")
202 ! Upper bound
203 ! Check that the specified field exist in the state
204 if (have_ub) then
205 if (.not. has_scalar_field(states(ub_state_id), ub_field_name)) then
206 ewrite(0, *) "Can not find the specified field ", trim(ub_field_name), " for the upper bound of control ", trim(control_name)
207 FLExit("Check your control's field settings.")
208 end if
209
210 ! Check that the control and the upper bound use the same mesh
211 sfield => extract_scalar_field(states(state_id), field_name)
212 sfield2 => extract_scalar_field(states(ub_state_id), ub_field_name)
213 if (.not. sfield%mesh == sfield2%mesh) then
214 ewrite(0, *) "Error in control ", trim(control_name), " definition. The upper bound and the control's mesh have to be the same."
215 FLExit("Check your control's field settings.")
216 end if
217 end if
218
219 ! Lower bound
220 if (have_lb) then
221 if (.not. has_scalar_field(states(state_id), lb_field_name)) then
222 ewrite(0, *) "Can not find the specified field ", trim(lb_field_name), " for the lower bound of control ", trim(control_name)
223 FLExit("Check your control's field settings.")
224 end if
225
226 ! Check that the control and the lower bound use the same mesh
227 sfield => extract_scalar_field(states(state_id), field_name)
228 sfield2 => extract_scalar_field(states(lb_state_id), lb_field_name)
229 if (.not. sfield%mesh == sfield2%mesh) then
230 ewrite(0, *) "Error in control ", trim(control_name), " definition. The lower bound and the control's mesh have to be the same."
231 FLExit("Check your control's field settings.")
232 end if
233 end if
234
235 case ("vector")
236 ! Upper bound
237 ! Check that the specified field exist in the state
238 if (have_ub) then
239 if (.not. has_vector_field(states(ub_state_id), ub_field_name)) then
240 ewrite(0, *) "Can not find the specified field ", trim(ub_field_name), " for the upper bound of control ", trim(control_name)
241 FLExit("Check your control's field settings.")
242 end if
243
244 ! Check that the control and the upper bound use the same mesh
245 vfield => extract_vector_field(states(state_id), field_name)
246 vfield2 => extract_vector_field(states(ub_state_id), ub_field_name)
247 if (.not. vfield%mesh == vfield2%mesh) then
248 ewrite(0, *) "Error in control ", trim(control_name), " definition. The upper bound and the control's mesh have to be the same."
249 FLExit("Check your control's field settings.")
250 end if
251 end if
252
253 ! Lower bound
254 if (have_lb) then
255 if (.not. has_vector_field(states(state_id), lb_field_name)) then
256 ewrite(0, *) "Can not find the specified field ", trim(lb_field_name), " for the lower bound of control ", trim(control_name)
257 FLExit("Check your control's field settings.")
258 end if
259
260 ! Check that the control and the lower bound use the same mesh
261 vfield => extract_vector_field(states(state_id), field_name)
262 vfield2 => extract_vector_field(states(lb_state_id), lb_field_name)
263 if (.not. vfield%mesh == vfield2%mesh) then
264 ewrite(0, *) "Error in control ", trim(control_name), " definition. The lower bound and the control's mesh have to be the same."
265 FLExit("Check your control's field settings.")
266 end if
267 end if
268
269 case ("tensor")
270 ! Upper bound
271 ! Check that the specified field exist in the state
272 if (have_ub) then
273 if (.not. has_tensor_field(states(ub_state_id), ub_field_name)) then
274 ewrite(0, *) "Can not find the specified field ", trim(ub_field_name), " for the upper bound of control ", trim(control_name)
275 FLExit("Check your control's field settings.")
276 end if
277
278 ! Check that the control and the upper bound use the same mesh
279 tfield => extract_tensor_field(states(state_id), field_name)
280 tfield2 => extract_tensor_field(states(ub_state_id), ub_field_name)
281 if (.not. tfield%mesh == tfield2%mesh) then
282 ewrite(0, *) "Error in control ", trim(control_name), " definition. The lower bound and the control's mesh have to be the same."
283 FLExit("Check your control's field settings.")
284 end if
285 end if
286
287 ! Lower bound
288 if (have_lb) then
289 if (.not. has_tensor_field(states(state_id), lb_field_name)) then
290 ewrite(0, *) "Can not find the specified field ", trim(lb_field_name), " for the lower bound of control ", trim(control_name)
291 FLExit("Check your control's field settings.")
292 end if
293
294 ! Check that the control and the lower bound use the same mesh
295 tfield => extract_tensor_field(states(state_id), field_name)
296 tfield2 => extract_tensor_field(states(lb_state_id), lb_field_name)
297 if (.not. sfield%mesh == sfield2%mesh) then
298 ewrite(0, *) "Error in control ", trim(control_name), " definition. The lower bound and the control's mesh have to be the same."
299 FLExit("Check your control's field settings.")
300 end if
301 end if
302
303 end select
304 end subroutine get_control_details
305
306 ! Loop through all controls in the option file and store them in files.
307 subroutine adjoint_write_controls(timestep, dt, states)
308 integer, intent(in) :: timestep
309 real, intent(in) :: dt
310 type(state_type), dimension(:), intent(in) :: states
311#ifdef HAVE_ADJOINT
312 integer :: nb_controls, i, state_id
313 logical :: active
314 character(len=OPTION_PATH_LEN) :: simulation_name, field_name, field_type, control_name
315 logical :: have_ub, have_lb
316 integer :: lb_state_id, ub_state_id
317 character(len=OPTION_PATH_LEN) :: lb_material_phase_name, ub_material_phase_name
318 character(len=OPTION_PATH_LEN) :: ub_field_name, lb_field_name
319
320 if (.not. have_option("/adjoint/controls")) then
321 return
322 end if
323
324 nb_controls = option_count("/adjoint/controls/control")
325 call get_option("/simulation_name", simulation_name)
326 ! Now loop over the controls and save them to disk
327 do i = 0, nb_controls-1
328 call get_control_details(states, timestep, i, control_name, state_id, field_name, field_type, active, have_lb, lb_state_id, lb_material_phase_name, lb_field_name, have_ub, ub_state_id, ub_material_phase_name, ub_field_name)
329 if (active) then
330
331 ! Save the control parameter to disk
332 call python_reset()
333 call python_add_state(states(state_id))
334 call python_run_string("import pickle;" // &
335 & "fname = 'control_" // trim(simulation_name) // "_" // trim(control_name) // "_" // int2str(timestep) // ".pkl';" // &
336 & "f = open(fname, 'wb');" // &
337 & "field = state." // trim(field_type) // "_fields['" // trim(field_name) // "'];" // &
338 & "pickle.dump(field.val[:], f);" // &
339 & "f.close();")
340
341 ! And its bounds
342 call python_reset()
343 if (have_lb) then
344 call python_add_state(states(lb_state_id))
345 call python_run_string("import pickle;" // &
346 & "fname = 'control_" // trim(simulation_name) // "_" // trim(control_name) // "_lower_bound_" // int2str(timestep) // ".pkl';" // &
347 & "f = open(fname, 'wb');" // &
348 & "field = state." // trim(field_type) // "_fields['" // trim(lb_field_name) // "'];" // &
349 & "pickle.dump(field.val[:], f);" // &
350 & "f.close();")
351 call python_reset()
352 end if
353
354 if (have_ub) then
355 call python_add_state(states(ub_state_id))
356 call python_run_string("import pickle;" // &
357 & "fname = 'control_" // trim(simulation_name) // "_" // trim(control_name) // "_upper_bound_" // int2str(timestep) // ".pkl';" // &
358 & "f = open(fname, 'wb');" // &
359 & "field = state." // trim(field_type) // "_fields['" // trim(ub_field_name) // "'];" // &
360 & "pickle.dump(field.val[:], f);" // &
361 & "f.close();")
362 call python_reset()
363 endif
364
365 end if
366 end do
367#endif
368 end subroutine adjoint_write_controls
369
370 ! The counterpart of adjoint_write_controls: Loop through all controls in the option file and fill the fields from the control files.
371 subroutine adjoint_load_controls(timestep, dt, states)
372 integer, intent(in) :: timestep
373 real, intent(in) :: dt
374 type(state_type), dimension(:), intent(in) :: states
375#ifdef HAVE_ADJOINT
376 integer :: nb_controls, i, state_id, s_idx
377 logical :: active, file_exists
378 character(len=OPTION_PATH_LEN) :: field_name, field_type, control_name, simulation_name, control_type
379
380 ! Do not read anything if we are supposed to write the controls
381 if (.not. have_option("/adjoint/controls/load_controls")) then
382 return
383 end if
384
385 call get_option("/simulation_name", simulation_name)
386 nb_controls = option_count("/adjoint/controls/control")
387
388 ! Now loop over the controls, read their controls files and fill the associated fields
389 do i = 0, nb_controls-1
390 call get_control_details(states, timestep, i, control_name, state_id, field_name, field_type, active)
391 call get_option("/adjoint/controls/control[" // int2str(i) // "]/type/name", control_type)
392
393 ! We load all OTHER controls, then apply our strong boundary conditions, then load BC controls
394 if (trim(control_type) == "boundary_condition") cycle
395
396 if (active) then
397 ! Check that the control parameter file extists
398 inquire(file="control_" // trim(simulation_name) // "_" // trim(control_name) // "_" // int2str(timestep) // ".pkl", exist=file_exists)
399 if (.not. file_exists) then
400 ewrite (0, *) "File 'control_" // trim(simulation_name) // "_" // trim(control_name) // &
401 & "_" // int2str(timestep) // ".pkl' does not exist."
402 FLExit("Error while loading control files. You might want to remove '/adjoint/controls/load_controls'?")
403 end if
404 ! Read the control parameter from disk
405 call python_reset()
406 call python_add_state(states(state_id))
407 call python_run_string("import pickle;" // &
408 & "fname = 'control_" // trim(simulation_name) // "_" // trim(control_name) // "_" // int2str(timestep) // ".pkl';" // &
409 & "f = open(fname, 'rb');" // &
410 & "field = state." // trim(field_type) // "_fields['" // trim(field_name) // "'];" // &
411 & "field.val[:] = pickle.load(f);" // &
412 & "f.close();")
413 call python_reset()
414 end if
415 end do
416
417 ! Now apply the BCs, because the BCs should overwrite (say) an initial_condition control
418 call set_dirichlet_consistent(states)
419
420 do i = 0, nb_controls-1
421 call get_control_details(states, timestep, i, control_name, state_id, field_name, field_type, active)
422 call get_option("/adjoint/controls/control[" // int2str(i) // "]/type/name", control_type)
423
424 ! We load all OTHER controls, then apply our strong boundary conditions, then load BC controls
425 if (trim(control_type) /= "boundary_condition") cycle
426
427 if (active) then
428 ! Check that the control parameter file extists
429 inquire(file="control_" // trim(simulation_name) // "_" // trim(control_name) // "_" // int2str(timestep) // ".pkl", exist=file_exists)
430 if (.not. file_exists) then
431 ewrite (0, *) "File 'control_" // trim(simulation_name) // "_" // trim(control_name) // &
432 & "_" // int2str(timestep) // ".pkl' does not exist."
433 FLExit("Error while loading control files. You might want to remove '/adjoint/controls/load_controls'?")
434 end if
435 ! Read the control parameter from disk
436 call python_reset()
437 call python_add_state(states(state_id))
438 call python_run_string("import pickle;" // &
439 & "fname = 'control_" // trim(simulation_name) // "_" // trim(control_name) // "_" // int2str(timestep) // ".pkl';" // &
440 & "f = open(fname, 'rb');" // &
441 & "field = state." // trim(field_type) // "_fields['" // trim(field_name) // "'];" // &
442 & "field.val[:] = pickle.load(f);" // &
443 & "f.close();")
444 call python_reset()
445 end if
446 end do
447#endif
448 end subroutine adjoint_load_controls
449
450 ! Extracts the total derivatives of the functional and saves them to disk.
451 subroutine adjoint_write_control_derivatives(states, timestep, functional_name)
452 type(state_type), dimension(:), intent(inout) :: states
453 integer, intent(in) :: timestep
454 character(len=*), intent(in) :: functional_name
455 character(len=OPTION_PATH_LEN) :: field_name, control_type, control_deriv_name, field_deriv_name, name, material_phase_name, simulation_name, field_type
456 integer :: nb_controls
457 integer :: i, state_id, s_idx
458 type(scalar_field), pointer :: sfield => null()
459 type(vector_field), pointer :: vfield => null()
460 type(tensor_field), pointer :: tfield => null()
461
462 if (.not. have_option("/adjoint/controls")) then
463 return
464 end if
465 call get_option("/simulation_name", simulation_name)
466 ! Remove the suffix _adjoint from the simulation_name
467
468 nb_controls = option_count("/adjoint/controls/control")
469 do i = 0, nb_controls-1
470 call get_option("/adjoint/controls/control[" // int2str(i) //"]/name", control_deriv_name)
471 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type/name", control_type)
472 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type::" // trim(control_type) // "/field_name", name)
473 s_idx = scan(trim(name), "::")
474 if (s_idx == 0) then
475 FLExit("The control " // trim(control_deriv_name) // " uses an invalid field_name. It should be of the form Materialphase::Fieldname")
476 end if
477 material_phase_name = name(1:s_idx - 1)
478 field_name = name(s_idx + 2:len_trim(name))
479 ! Find state associated with the material phase
480 do state_id = 1, size(states)
481 if (trim(states(state_id)%name) == trim(material_phase_name)) then
482 exit
483 end if
484 end do
485 ! Make sure we found the state
486 if (.not. trim(states(state_id)%name) == trim(material_phase_name)) then
487 FLExit("Could not find state " // trim(material_phase_name) // " as specified in control " // trim(control_deriv_name) // ".")
488 end if
489
490 field_name = "Adjoint" // trim(field_name)
491 control_deriv_name = trim(control_deriv_name) // "_TotalDerivative"
492 if (trim(control_type) == "initial_condition" .or. trim(control_type) == "source_term") then
493
494 if (trim(control_type) == "initial_condition" .and. timestep > 0) then
495 cycle
496 end if
497
498 if (trim(control_type) == "source_term" .and. timestep == 0) then
499 cycle
500 end if
501
502 field_deriv_name = trim(functional_name) // "_" // control_deriv_name
503 if (has_scalar_field(states(state_id), field_name)) then
504 field_type = "scalar"
505 elseif (has_vector_field(states(state_id), field_name)) then
506 field_type = "vector"
507 elseif (has_tensor_field(states(state_id), field_name)) then
508 field_type = "tensor"
509 else
510 ewrite(0, *) "The control field " // trim(field_deriv_name) // " specified in control " // trim(control_deriv_name) // " is not a field in the state."
511 ewrite(0, *) "The current state is: "
512 call print_state(states(state_id))
513 FLExit("Check your control's field settings.")
514 end if
515 elseif (trim(control_type) == "boundary_condition") then
516 FLAbort("Boundary condition control not implemented yet.")
517 end if
518 ! Save the control parameter to disk
519 call python_reset()
520 call python_add_state(states(state_id))
521 call python_run_string("import pickle;" // &
522 & "fname = 'control_" // trim(simulation_name) // "_" // trim(control_deriv_name) // "_" // int2str(timestep) // ".pkl';" // &
523 & "f = open(fname, 'wb');" // &
524 & "field = state." // trim(field_type) // "_fields['" // trim(field_deriv_name) // "'];" // &
525 & "pickle.dump(field.val[:], f);" // &
526 & "f.close();")
527 call python_reset()
528 end do
529 end subroutine adjoint_write_control_derivatives
530
531 subroutine allocate_and_insert_control_derivative_fields(states)
532 type(state_type), dimension(:), intent(inout) :: states
533 integer :: nb_controls, nb_functionals, i, state_id, functional, s_idx
534 character(len=OPTION_PATH_LEN) :: field_name, control_type, control_deriv_name, functional_name, field_deriv_name, material_phase_name, name
535 type(scalar_field), pointer :: sfield => null()
536 type(vector_field), pointer :: vfield => null()
537 type(tensor_field), pointer :: tfield => null()
538 type(scalar_field) :: sfield_deriv
539 type(vector_field) :: vfield_deriv
540 type(tensor_field) :: tfield_deriv
541
542 nb_controls = option_count("/adjoint/controls/control")
543 nb_functionals = option_count("/adjoint/functional")
544 ! Loop over the functionals
545 do functional = 0, nb_functionals-1
546 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
547 ! Now loop over the controls
548 do i = 0, nb_controls-1
549 call get_option("/adjoint/controls/control[" // int2str(i) //"]/name", control_deriv_name)
550 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type/name", control_type)
551 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type::" // trim(control_type) // "/field_name", name)
552 s_idx = scan(trim(name), "::")
553 if (s_idx == 0) then
554 FLExit("The control " // trim(control_deriv_name) // " uses an invalid field_name. It should be of the form Materialphase::Fieldname")
555 end if
556 material_phase_name = name(1:s_idx - 1)
557 field_name = name(s_idx + 2:len_trim(name))
558 ! Find state associated with the material phase
559 do state_id = 1, size(states)
560 if (trim(states(state_id)%name) == trim(material_phase_name)) then
561 exit
562 end if
563 end do
564 ! Make sure we found the state
565 if (.not. trim(states(state_id)%name) == trim(material_phase_name)) then
566 FLExit("Could not find state " // trim(material_phase_name) // " as specified in control " // trim(control_deriv_name) // ".")
567 end if
568
569 field_name = "Adjoint" // trim(field_name)
570 control_deriv_name = trim(control_deriv_name) // "_TotalDerivative"
571
572 if (trim(control_type) == "initial_condition" .or. trim(control_type) == "source_term") then
573 field_deriv_name = trim(functional_name) // "_" // control_deriv_name
574
575 if (has_scalar_field(states(state_id), field_name)) then
576 sfield => extract_scalar_field(states(state_id), field_name)
577 call allocate(sfield_deriv, sfield%mesh, field_deriv_name)
578 call zero(sfield_deriv)
579 call insert(states(state_id), sfield_deriv, field_deriv_name)
580 call deallocate(sfield_deriv)
581
582 elseif (has_vector_field(states(state_id), field_name)) then
583 vfield => extract_vector_field(states(state_id), field_name)
584 call allocate(vfield_deriv, vfield%dim, vfield%mesh, field_deriv_name)
585 call zero(vfield_deriv)
586 call insert(states(state_id), vfield_deriv, field_deriv_name)
587 call deallocate(vfield_deriv)
588
589 elseif (has_tensor_field(states(state_id), field_name)) then
590 tfield => extract_tensor_field(states(state_id), field_name)
591 call allocate(tfield_deriv, tfield%mesh, field_deriv_name, tfield%field_type, tfield%dim)
592 call zero(tfield_deriv)
593 call insert(states(state_id), tfield_deriv, field_deriv_name)
594 call deallocate(tfield_deriv)
595
596 else
597 ewrite(0, *) "The control field " // trim(field_name) // " specified in control " // trim(control_deriv_name) // " is not a field in the state."
598 ewrite(0, *) "The current state is: "
599 call print_state(states(state_id))
600 FLExit("Check your control's field settings.")
601 end if
602
603 elseif (trim(control_type) == "boundary_condition") then
604 FLAbort("Boundary condition control not implemented yet.")
605 end if
606
607 end do
608 end do
609 end subroutine allocate_and_insert_control_derivative_fields
610
611end module adjoint_controls
0612
=== modified file 'adjoint/Adjoint_Functional_Evaluation.F90'
--- adjoint/Adjoint_Functional_Evaluation.F90 2011-05-20 17:42:50 +0000
+++ adjoint/Adjoint_Functional_Evaluation.F90 2011-07-12 15:56:32 +0000
@@ -48,7 +48,7 @@
48 implicit none48 implicit none
4949
50 private50 private
51 public :: libadjoint_functional_derivative, adj_record_anything_necessary51 public :: libadjoint_evaluate_functional, libadjoint_functional_derivative, adj_record_anything_necessary
5252
53 contains53 contains
5454
@@ -250,32 +250,6 @@
250 end if250 end if
251251
252 if (has_func) then252 if (has_func) then
253 if (.not. functional_computed) then
254 ierr = adj_timestep_get_times(adjointer, timelevel, start_time, end_time)
255 call adj_chkierr(ierr)
256 assert(start_time < end_time)
257
258 write(buffer,*) timelevel + 1
259 call python_run_string("n = " // trim(buffer))
260
261 write(buffer,*) start_time
262 call python_run_string("time = " // trim(buffer))
263
264 write(buffer, *) abs(start_time - end_time)
265 call python_run_string("dt = " // trim(buffer))
266
267 call python_run_string(trim(code_func))
268 J = python_fetch_real("J")
269
270 ! So we've computed the component of the functional associated with this timestep.
271 ! We also want to sum them all up ...
272
273 call set_diagnostic(name=trim(functional_name_f) // "_component", statistic="value", value=(/J/))
274 fn_value => get_diagnostic(name=trim(functional_name_f), statistic="value")
275 J = J + fn_value(1)
276 call set_diagnostic(name=trim(functional_name_f), statistic="value", value=(/J/))
277 functional_computed = .true.
278 end if
279253
280 if (.not. has_deriv) then254 if (.not. has_deriv) then
281 check_uncertainties = "try: " // achar(10) // &255 check_uncertainties = "try: " // achar(10) // &
@@ -341,6 +315,111 @@
341315
342 end subroutine libadjoint_functional_derivative316 end subroutine libadjoint_functional_derivative
343317
318 subroutine libadjoint_evaluate_functional(adjointer, timelevel, ndepends, dependencies, values, functional_name_c, output) bind(c)
319 use iso_c_binding
320 use libadjoint_data_structures
321 type(adj_adjointer), intent(in) :: adjointer
322 integer(kind=c_int), intent(in), value :: timelevel
323 integer(kind=c_int), intent(in), value :: ndepends
324 type(adj_variable), dimension(ndepends), intent(in) :: dependencies
325 type(adj_vector), dimension(ndepends), intent(in) :: values
326 character(kind=c_char), dimension(ADJ_NAME_LEN), intent(in) :: functional_name_c
327 adj_scalar_f, intent(out) :: output
328
329 type(state_type), dimension(:,:), pointer :: states ! material_phases x timelevels
330 character(len=ADJ_NAME_LEN) :: functional_name_f
331 logical :: has_func
332 character(len=PYTHON_FUNC_LEN) :: code_func
333 integer :: ierr, max_timelevel, tmp_timelevel, min_timelevel, nmaterial_phases
334 character(len=OPTION_PATH_LEN) :: material_phase_name
335 integer :: no_timesteps, timestep, i
336 real :: start_time, end_time
337 character(len = 30) :: buffer, buffer2
338
339 call python_reset
340
341 functional_name_f = ' '
342 i = 1
343 do while (i <= ADJ_NAME_LEN .and. functional_name_c(i) /= c_null_char)
344 functional_name_f(i:i) = functional_name_c(i)
345 i = i + 1
346 end do
347
348 ! Fetch the python code the user has helpfully supplied.
349 has_func = have_option("/adjoint/functional::" // trim(functional_name_f) // "/functional_value/algorithm")
350 if (.not. has_func) then
351 FLAbort("You need to supply code for the functional to evaluate it!")
352 endif
353
354 if (has_func) then
355 call get_option("/adjoint/functional::" // trim(functional_name_f) // "/functional_value/algorithm", code_func)
356 endif
357
358 if (ndepends==0) then
359 max_timelevel = 0
360 min_timelevel = 0
361 else
362 ! Convert from the list of adj_values/adj_vectors to actual states
363 ierr = adj_variable_get_timestep(dependencies(1), max_timelevel)
364 min_timelevel = max_timelevel
365 do i=1,ndepends
366 ierr = adj_variable_get_timestep(dependencies(i), tmp_timelevel)
367 max_timelevel = max(max_timelevel, tmp_timelevel)
368 min_timelevel = min(min_timelevel, tmp_timelevel)
369 end do
370 end if
371
372 nmaterial_phases = option_count("/material_phase")
373 allocate(states(nmaterial_phases, min_timelevel:max_timelevel))
374
375 ! Set the names of the material phases, so that we can look them up and know
376 ! which material_phase to put stuff into in convert_adj_vectors_to_states
377 do i=0,nmaterial_phases-1
378 call get_option("/material_phase[" // int2str(i) // "]/name", material_phase_name)
379 states(i+1,:)%name = trim(material_phase_name)
380 end do
381 call convert_adj_vectors_to_states(dependencies, values, states)
382 call python_add_states_time(states)
383
384 ! Also set up some useful variables for the user to use
385 ierr = adj_timestep_count(adjointer, no_timesteps)
386 call adj_chkierr(ierr)
387 write(buffer, *) no_timesteps
388 call python_run_string("times = [0] * " // trim(buffer))
389 do timestep=0,no_timesteps-2
390 ierr = adj_timestep_get_times(adjointer, timestep, start_time, end_time)
391 call adj_chkierr(ierr)
392 write(buffer, '(i0)') timestep
393 write(buffer2, *) start_time
394 call python_run_string("times[" // trim(buffer) // "] = " // trim(buffer2))
395 write(buffer, '(i0)') timestep+1
396 write(buffer2, *) end_time
397 call python_run_string("times[" // trim(buffer) // "] = " // trim(buffer2))
398 end do
399
400 ierr = adj_timestep_get_times(adjointer, timelevel, start_time, end_time)
401 call adj_chkierr(ierr)
402 assert(start_time < end_time)
403
404 write(buffer,*) timelevel + 1
405 call python_run_string("n = " // trim(buffer))
406
407 write(buffer,*) start_time
408 call python_run_string("time = " // trim(buffer))
409
410 write(buffer, *) abs(start_time - end_time)
411 call python_run_string("dt = " // trim(buffer))
412
413 call python_run_string(trim(code_func))
414 output = python_fetch_real("J")
415
416 if (max_timelevel >= 0) then
417 call deallocate(states)
418 deallocate(states)
419 endif
420
421 end subroutine libadjoint_evaluate_functional
422
344 subroutine convert_adj_vectors_to_states(dependencies, values, states)423 subroutine convert_adj_vectors_to_states(dependencies, values, states)
345 type(adj_variable), dimension(:), intent(in) :: dependencies424 type(adj_variable), dimension(:), intent(in) :: dependencies
346 type(adj_vector), dimension(:), intent(in) :: values425 type(adj_vector), dimension(:), intent(in) :: values
@@ -432,7 +511,7 @@
432 call get_option("/timestepping/finish_time", finish_time)511 call get_option("/timestepping/finish_time", finish_time)
433512
434 call get_option("/adjoint/functional::" // trim(functional) // "/functional_dependencies/algorithm", buf)513 call get_option("/adjoint/functional::" // trim(functional) // "/functional_dependencies/algorithm", buf)
435 call adj_variables_from_python(buf, current_time, finish_time, python_timestep, vars)514 call adj_variables_from_python(adjointer, buf, current_time, finish_time, python_timestep, vars)
436515
437 variable_loop: do j=1,size(vars)516 variable_loop: do j=1,size(vars)
438 ierr = adj_variable_get_timestep(vars(j), var_timestep)517 ierr = adj_variable_get_timestep(vars(j), var_timestep)
@@ -522,5 +601,6 @@
522601
523 deallocate(vars)602 deallocate(vars)
524 end subroutine adj_record_anything_necessary603 end subroutine adj_record_anything_necessary
604
525#endif605#endif
526end module adjoint_functional_evaluation606end module adjoint_functional_evaluation
527607
=== modified file 'adjoint/Adjoint_Global_Variables.F90'
--- adjoint/Adjoint_Global_Variables.F90 2011-04-01 17:40:34 +0000
+++ adjoint/Adjoint_Global_Variables.F90 2011-07-12 15:56:32 +0000
@@ -35,6 +35,5 @@
3535
36 type(adj_dictionary) :: adj_path_lookup, adj_solver_path_lookup36 type(adj_dictionary) :: adj_path_lookup, adj_solver_path_lookup
37 type(adj_adjointer) :: adjointer37 type(adj_adjointer) :: adjointer
38 logical :: functional_computed = .false.
39#endif38#endif
40end module adjoint_global_variables39end module adjoint_global_variables
4140
=== modified file 'adjoint/Adjoint_Main_Loop.F90'
--- adjoint/Adjoint_Main_Loop.F90 2011-05-11 17:15:33 +0000
+++ adjoint/Adjoint_Main_Loop.F90 2011-07-12 15:56:32 +0000
@@ -39,6 +39,7 @@
39 use global_parameters, only: OPTION_PATH_LEN, running_adjoint39 use global_parameters, only: OPTION_PATH_LEN, running_adjoint
40 use adjoint_global_variables40 use adjoint_global_variables
41 use adjoint_functional_evaluation41 use adjoint_functional_evaluation
42 use adjoint_controls
42 use populate_state_module43 use populate_state_module
43 use signal_vars44 use signal_vars
44 use mangle_options_tree45 use mangle_options_tree
@@ -53,7 +54,6 @@
53 implicit none54 implicit none
5455
55 private56 private
56 public :: adjoint_main_loop_register_diagnostic
57#ifdef HAVE_ADJOINT57#ifdef HAVE_ADJOINT
58 public :: compute_adjoint58 public :: compute_adjoint
59#endif59#endif
@@ -61,9 +61,28 @@
61 contains61 contains
6262
63#ifdef HAVE_ADJOINT63#ifdef HAVE_ADJOINT
64 subroutine compute_adjoint(state, dump_no)64 ! Computes the adjoint equation
65 ! The optional adjoint timestep callback is called for each functional after every timestep in the adjoint loop.
66 ! It is commonly used to compute the diangostics from the adjoint solution, e.g. the total derivative of the functional.
67 subroutine compute_adjoint(state, dump_no, adjoint_timestep_callback, adjoint_timestep_callback_data)
68 use iso_c_binding, only: c_ptr
65 type(state_type), dimension(:), intent(inout) :: state69 type(state_type), dimension(:), intent(inout) :: state
66 integer, intent(inout) :: dump_no70 integer, intent(inout) :: dump_no
71 optional :: adjoint_timestep_callback
72 ! Data is a void pointer used to pass variables into the callback
73 type(c_ptr), intent(in), optional :: adjoint_timestep_callback_data
74 interface
75 subroutine adjoint_timestep_callback(state, timestep, functional_name, data)
76 use iso_c_binding, only: c_ptr
77 use global_parameters, only: OPTION_PATH_LEN
78 use state_module
79 type(state_type), dimension(:), intent(inout) :: state
80 integer, intent(in) :: timestep
81 character(len=OPTION_PATH_LEN), intent(in) :: functional_name
82 ! Data is a void pointer used to pass variables into the callback
83 type(c_ptr), intent(in) :: data
84 end subroutine adjoint_timestep_callback
85 end interface
6786
68 type(adj_vector) :: rhs87 type(adj_vector) :: rhs
69 type(adj_vector) :: soln88 type(adj_vector) :: soln
@@ -80,10 +99,12 @@
80 integer :: end_timestep, start_timestep, no_timesteps, timestep99 integer :: end_timestep, start_timestep, no_timesteps, timestep
81 real :: start_time, end_time100 real :: start_time, end_time
82101
83 character(len=OPTION_PATH_LEN) :: simulation_base_name, functional_name102 character(len=OPTION_PATH_LEN) :: simulation_base_name
84 type(stat_type), dimension(:), allocatable :: functional_stats103 type(stat_type), dimension(:), allocatable :: functional_stats
104 real :: J
105 real, dimension(:), pointer :: fn_value
85106
86 character(len=ADJ_NAME_LEN) :: variable_name, field_name, material_phase_name107 character(len=ADJ_NAME_LEN) :: variable_name, field_name, material_phase_name, functional_name
87 type(scalar_field) :: sfield_soln, sfield_rhs108 type(scalar_field) :: sfield_soln, sfield_rhs
88 type(vector_field) :: vfield_soln, vfield_rhs109 type(vector_field) :: vfield_soln, vfield_rhs
89 type(csr_matrix) :: csr_mat110 type(csr_matrix) :: csr_mat
@@ -112,17 +133,29 @@
112 allocate(functional_stats(no_functionals))133 allocate(functional_stats(no_functionals))
113134
114 do functional=0,no_functionals-1135 do functional=0,no_functionals-1
136 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
137 if (have_option("/adjoint/functional::" // trim(functional_name) // "/disable_adjoint_run")) then
138 cycle
139 end if
115 default_stat = functional_stats(functional + 1)140 default_stat = functional_stats(functional + 1)
116 call initialise_walltime141 call initialise_walltime
117 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
118 call initialise_diagnostics(trim(simulation_base_name) // '_' // trim(functional_name), state)142 call initialise_diagnostics(trim(simulation_base_name) // '_' // trim(functional_name), state)
119 functional_stats(functional + 1) = default_stat143 functional_stats(functional + 1) = default_stat
120144
145 ! Register the callback to compute J
146 ierr = adj_register_functional_callback(adjointer, trim(functional_name), c_funloc(libadjoint_evaluate_functional))
147 call adj_chkierr(ierr)
148
121 ! Register the callback to compute delJ/delu149 ! Register the callback to compute delJ/delu
122 ierr = adj_register_functional_derivative_callback(adjointer, trim(functional_name), c_funloc(libadjoint_functional_derivative))150 ierr = adj_register_functional_derivative_callback(adjointer, trim(functional_name), c_funloc(libadjoint_functional_derivative))
123 call adj_chkierr(ierr)151 call adj_chkierr(ierr)
124 end do152 end do
125153
154 ! Insert the fields for storing the derivatives of the functionals with respect to the controls into the state
155 if (have_option("/adjoint/controls")) then
156 call allocate_and_insert_control_derivative_fields(state)
157 end if
158
126 ierr = adj_timestep_count(adjointer, no_timesteps)159 ierr = adj_timestep_count(adjointer, no_timesteps)
127 call adj_chkierr(ierr)160 call adj_chkierr(ierr)
128161
@@ -145,18 +178,6 @@
145 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)178 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
146 call set_option("/simulation_name", trim(simulation_base_name) // "_" // trim(functional_name))179 call set_option("/simulation_name", trim(simulation_base_name) // "_" // trim(functional_name))
147 default_stat = functional_stats(functional + 1)180 default_stat = functional_stats(functional + 1)
148 ! We don't want to compute a functional for the dummy timestep added at the end to act
149 ! as a container for the last equation
150 if (start_time == end_time) then
151 assert(timestep == no_timesteps-1)
152 if (have_option("/adjoint/functional[" // int2str(functional) // "]/functional_value")) then
153 call set_diagnostic(name=trim(functional_name), statistic="value", value=(/0.0/))
154 call set_diagnostic(name=trim(functional_name) // "_component", statistic="value", value=(/0.0/))
155 end if
156 functional_computed = .true.
157 else
158 functional_computed = .false.
159 end if
160181
161 do equation=end_timestep,start_timestep,-1182 do equation=end_timestep,start_timestep,-1
162 ierr = adj_get_adjoint_equation(adjointer, equation, trim(functional_name), lhs, rhs, adj_var)183 ierr = adj_get_adjoint_equation(adjointer, equation, trim(functional_name), lhs, rhs, adj_var)
@@ -201,7 +222,7 @@
201 end if222 end if
202223
203 call petsc_solve(sfield_soln, csr_mat, sfield_rhs, option_path=path)224 call petsc_solve(sfield_soln, csr_mat, sfield_rhs, option_path=path)
204 !call compute_inactive_rows(sfield_soln, csr_mat, sfield_rhs)225 call compute_inactive_rows(sfield_soln, csr_mat, sfield_rhs)
205 endif226 endif
206 case(ADJ_BLOCK_CSR_MATRIX)227 case(ADJ_BLOCK_CSR_MATRIX)
207 FLAbort("Cannot map between scalar fields with a block_csr_matrix .. ")228 FLAbort("Cannot map between scalar fields with a block_csr_matrix .. ")
@@ -240,7 +261,7 @@
240 end if261 end if
241262
242 call petsc_solve(vfield_soln, csr_mat, vfield_rhs, option_path=path)263 call petsc_solve(vfield_soln, csr_mat, vfield_rhs, option_path=path)
243 call compute_inactive_rows(vfield_soln, csr_mat, vfield_rhs)264 !call compute_inactive_rows(vfield_soln, csr_mat, vfield_rhs)
244 endif265 endif
245 case(ADJ_BLOCK_CSR_MATRIX)266 case(ADJ_BLOCK_CSR_MATRIX)
246 call matrix_from_adj_matrix(lhs, block_csr_mat)267 call matrix_from_adj_matrix(lhs, block_csr_mat)
@@ -282,7 +303,16 @@
282 call adjoint_cleanup303 call adjoint_cleanup
283 return304 return
284 end if305 end if
285 end do306 end do ! End of equation loop
307
308 ! Callback for the computation of the functional total derivatives
309 if (present(adjoint_timestep_callback)) then
310 call adjoint_timestep_callback(state, timestep, trim(functional_name), data=adjoint_timestep_callback_data)
311 end if
312 if (have_option("/adjoint/controls")) then
313 ! Write the functional's total derivatives to file
314 call adjoint_write_control_derivatives(state, timestep, trim(functional_name))
315 end if
286316
287 call calculate_diagnostic_variables(state, exclude_nonrecalculated = .true.)317 call calculate_diagnostic_variables(state, exclude_nonrecalculated = .true.)
288 call calculate_diagnostic_variables_new(state, exclude_nonrecalculated = .true.)318 call calculate_diagnostic_variables_new(state, exclude_nonrecalculated = .true.)
@@ -296,13 +326,13 @@
296 endif326 endif
297327
298 functional_stats(functional + 1) = default_stat328 functional_stats(functional + 1) = default_stat
299 end do329 end do ! End of functional loop
300330
301 ! Now forget331 ! Now forget
302 ierr = adj_forget_adjoint_equation(adjointer, start_timestep)332 ierr = adj_forget_adjoint_equation(adjointer, start_timestep)
303 call adj_chkierr(ierr)333 call adj_chkierr(ierr)
304 current_time = start_time334 current_time = start_time
305 end do335 end do ! End of timestep loop
306336
307 call get_option("/timestepping/finish_time", finish_time)337 call get_option("/timestepping/finish_time", finish_time)
308 assert(current_time == finish_time)338 assert(current_time == finish_time)
@@ -314,6 +344,10 @@
314 subroutine adjoint_cleanup344 subroutine adjoint_cleanup
315 ! Clean up stat files345 ! Clean up stat files
316 do functional=0,no_functionals-1346 do functional=0,no_functionals-1
347 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
348 if (have_option("/adjoint/functional::" // trim(functional_name) // "/disable_adjoint_run")) then
349 cycle
350 end if
317 default_stat = functional_stats(functional + 1)351 default_stat = functional_stats(functional + 1)
318 call close_diagnostic_files352 call close_diagnostic_files
319 call uninitialise_diagnostics353 call uninitialise_diagnostics
@@ -325,23 +359,7 @@
325 call adj_chkierr(ierr)359 call adj_chkierr(ierr)
326 end subroutine adjoint_cleanup360 end subroutine adjoint_cleanup
327 end subroutine compute_adjoint361 end subroutine compute_adjoint
362
328#endif363#endif
329364
330 subroutine adjoint_main_loop_register_diagnostic
331 integer :: functional, no_functionals
332 character(len=OPTION_PATH_LEN) :: functional_name
333
334 no_functionals = option_count("/adjoint/functional")
335
336 do functional=0,no_functionals-1
337 ! Register a diagnostic for each functional
338 if (have_option("/adjoint/functional[" // int2str(functional) // "]/functional_value")) then
339 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
340 call register_diagnostic(dim=1, name=trim(functional_name) // "_component", statistic="value")
341 call register_diagnostic(dim=1, name=trim(functional_name), statistic="value")
342 end if
343 end do
344
345 end subroutine adjoint_main_loop_register_diagnostic
346
347end module adjoint_main_loop365end module adjoint_main_loop
348366
=== modified file 'adjoint/Adjoint_Python_Fortran.F90'
--- adjoint/Adjoint_Python_Fortran.F90 2011-05-01 19:08:55 +0000
+++ adjoint/Adjoint_Python_Fortran.F90 2011-07-12 15:56:32 +0000
@@ -40,9 +40,11 @@
40 public :: adj_variables_from_python40 public :: adj_variables_from_python
4141
42 interface42 interface
43 subroutine adj_variables_from_python_c(fn, fnlen, start_time, end_time, timestep, result, result_len, stat) &43 subroutine adj_variables_from_python_c(adjointer, fn, fnlen, start_time, end_time, timestep, result, result_len, stat) &
44 & bind(c, name='adj_variables_from_python')44 & bind(c, name='adj_variables_from_python')
45 use libadjoint
45 use iso_c_binding46 use iso_c_binding
47 type(adj_adjointer), intent(in) :: adjointer
46 integer(kind=c_int), intent(in), value :: fnlen48 integer(kind=c_int), intent(in), value :: fnlen
47 character(kind=c_char), dimension(fnlen), intent(in) :: fn49 character(kind=c_char), dimension(fnlen), intent(in) :: fn
48 real(kind=c_double), intent(in), value :: start_time, end_time50 real(kind=c_double), intent(in), value :: start_time, end_time
@@ -60,7 +62,8 @@
6062
61 contains63 contains
6264
63 subroutine adj_variables_from_python(fn, start_time, end_time, timestep, result, extras, stat)65 subroutine adj_variables_from_python(adjointer, fn, start_time, end_time, timestep, result, extras, stat)
66 type(adj_adjointer), intent(in) :: adjointer
64 character(len=*), intent(in) :: fn67 character(len=*), intent(in) :: fn
65 real, intent(in) :: start_time, end_time68 real, intent(in) :: start_time, end_time
66 integer, intent(in) :: timestep69 integer, intent(in) :: timestep
@@ -88,7 +91,7 @@
8891
89 timestep_long = timestep92 timestep_long = timestep
9093
91 call adj_variables_from_python_c(fn_c, len_trim(fn), start_time, end_time, timestep_long, result_c_ptr, result_len_c, stat_c)94 call adj_variables_from_python_c(adjointer, fn_c, len_trim(fn), start_time, end_time, timestep_long, result_c_ptr, result_len_c, stat_c)
9295
93 if (stat_c /= 0) then96 if (stat_c /= 0) then
94 if (present(stat)) then97 if (present(stat)) then
9598
=== modified file 'adjoint/Burgers_Adjoint_Callbacks.F90'
--- adjoint/Burgers_Adjoint_Callbacks.F90 2011-04-01 17:40:34 +0000
+++ adjoint/Burgers_Adjoint_Callbacks.F90 2011-07-12 15:56:32 +0000
@@ -40,6 +40,9 @@
40 use adjoint_global_variables, only: adj_path_lookup40 use adjoint_global_variables, only: adj_path_lookup
41 use mangle_options_tree, only: adjoint_field_path41 use mangle_options_tree, only: adjoint_field_path
42 use mangle_dirichlet_rows_module42 use mangle_dirichlet_rows_module
43 use populate_state_module
44 use burgers_assembly
45 use global_parameters, only: OPTION_PATH_LEN, running_adjoint
43 implicit none46 implicit none
4447
45 private48 private
@@ -61,6 +64,15 @@
61 call adj_chkierr(ierr)64 call adj_chkierr(ierr)
62 ierr = adj_register_operator_callback(adjointer, ADJ_BLOCK_ACTION_CB, "TimesteppingOperator", c_funloc(timestepping_operator_action_callback))65 ierr = adj_register_operator_callback(adjointer, ADJ_BLOCK_ACTION_CB, "TimesteppingOperator", c_funloc(timestepping_operator_action_callback))
63 call adj_chkierr(ierr)66 call adj_chkierr(ierr)
67
68 ierr = adj_register_operator_callback(adjointer, ADJ_NBLOCK_DERIVATIVE_ACTION_CB, "AdvectionOperator", c_funloc(advection_derivative_action_proc))
69 call adj_chkierr(ierr)
70
71 ierr = adj_register_operator_callback(adjointer, ADJ_NBLOCK_ACTION_CB, "AdvectionOperator", c_funloc(advection_action_proc))
72 call adj_chkierr(ierr)
73
74 ierr = adj_register_forward_source_callback(adjointer, c_funloc(burgers_equation_forward_source))
75 call adj_chkierr(ierr)
64 end subroutine register_burgers_operator_callbacks76 end subroutine register_burgers_operator_callbacks
6577
66 subroutine velocity_identity_assembly_callback(nvar, variables, dependencies, hermitian, coefficient, context, output, rhs) bind(c)78 subroutine velocity_identity_assembly_callback(nvar, variables, dependencies, hermitian, coefficient, context, output, rhs) bind(c)
@@ -114,9 +126,11 @@
114 type(scalar_field) :: empty_velocity_field, previous_u, iter_u126 type(scalar_field) :: empty_velocity_field, previous_u, iter_u
115 type(scalar_field), dimension(2) :: deps127 type(scalar_field), dimension(2) :: deps
116 type(csr_matrix), pointer :: mass_mat, diffusion_mat128 type(csr_matrix), pointer :: mass_mat, diffusion_mat
117 type(csr_matrix) :: burgers_mat, burgers_mat_T129 type(csr_matrix) :: burgers_mat, burgers_mat_T, advection_mat
130 type(vector_field), pointer :: positions
118 real :: dt, theta131 real :: dt, theta
119 integer :: i132 integer :: i
133 character(len=FIELD_NAME_LEN) :: path
120134
121 if (coefficient /= 1.0) then135 if (coefficient /= 1.0) then
122 FLAbort("The coefficient in burgers_operator_assembly_callback has to be 1.0")136 FLAbort("The coefficient in burgers_operator_assembly_callback has to be 1.0")
@@ -139,13 +153,20 @@
139 FLAbort("Unknown number of dependencies in burgers_operator_assembly_callback")153 FLAbort("Unknown number of dependencies in burgers_operator_assembly_callback")
140 end if154 end if
141155
142 call get_option(trim(adjoint_field_path("/material_phase::Fluid/scalar_field::Velocity/prognostic/temporal_discretisation/theta")), theta)156 path = "/material_phase::Fluid/scalar_field::Velocity"
157 if (running_adjoint) then
158 path = adjoint_field_path("/material_phase::Fluid/scalar_field::Velocity")
159 end if
160
161 call get_option(trim(path) // "/prognostic/temporal_discretisation/theta", theta, default=0.5)
143 call get_option("/timestepping/timestep", dt)162 call get_option("/timestepping/timestep", dt)
163 dt = abs(dt)
144164
145 call c_f_pointer(context, matrices)165 call c_f_pointer(context, matrices)
146 u_mesh => extract_mesh(matrices, "VelocityMesh")166 u_mesh => extract_mesh(matrices, "VelocityMesh")
147 diffusion_mat => extract_csr_matrix(matrices, "DiffusionMatrix")167 diffusion_mat => extract_csr_matrix(matrices, "DiffusionMatrix")
148 mass_mat => extract_csr_matrix(matrices, "MassMatrix")168 mass_mat => extract_csr_matrix(matrices, "MassMatrix")
169 positions => extract_vector_field(matrices, "Coordinate")
149170
150 call allocate(empty_velocity_field, u_mesh, trim("AdjointPressureRhs"))171 call allocate(empty_velocity_field, u_mesh, trim("AdjointPressureRhs"))
151 call zero(empty_velocity_field)172 call zero(empty_velocity_field)
@@ -156,10 +177,18 @@
156 call allocate(burgers_mat, mass_mat%sparsity, name="BurgersAdjointOutput")177 call allocate(burgers_mat, mass_mat%sparsity, name="BurgersAdjointOutput")
157 call zero(burgers_mat)178 call zero(burgers_mat)
158179
159 if (.not. have_option(trim(adjoint_field_path('/material_phase::Fluid/scalar_field::Velocity/prognostic/temporal_discretisation/remove_time_term')))) then180 if (.not. have_option(trim(path) // '/prognostic/temporal_discretisation/remove_time_term')) then
160 call addto(burgers_mat, mass_mat, 1.0/abs(dt))181 call addto(burgers_mat, mass_mat, 1.0/abs(dt))
161 end if182 end if
162 !call addto(burgers_mat, advection_mat, theta)183
184 if (.not. have_option(trim(path) // '/prognostic/remove_advection_term')) then
185 call allocate(advection_mat, mass_mat%sparsity, name="BurgersCallbackAdvectionMatrix")
186 call zero(advection_mat)
187 call assemble_advection_matrix(advection_mat, positions, previous_u, iter_u)
188 call addto(burgers_mat, advection_mat, theta)
189 call deallocate(advection_mat)
190 end if
191
163 call addto(burgers_mat, diffusion_mat, theta)192 call addto(burgers_mat, diffusion_mat, theta)
164193
165 ! Ensure that the input velocity has indeed dirichlet bc attached194 ! Ensure that the input velocity has indeed dirichlet bc attached
@@ -223,12 +252,15 @@
223252
224 type(state_type), pointer :: matrices253 type(state_type), pointer :: matrices
225 type(csr_matrix), pointer :: diffusion_mat, mass_mat254 type(csr_matrix), pointer :: diffusion_mat, mass_mat
226 type(csr_matrix) :: timestepping_mat
227 type(mesh_type), pointer :: u_mesh255 type(mesh_type), pointer :: u_mesh
228 ! Input/output variables256 ! Input/output variables
229 type(scalar_field) :: u_input, previous_u, iter_u257 type(scalar_field) :: u_input, previous_u, iter_u
230 type(scalar_field) :: u_output258 type(scalar_field) :: u_output, tmp_u
231 real :: theta, dt259 real :: theta, dt
260 character(len=FIELD_NAME_LEN) :: path
261 type(csr_matrix) :: advection_mat
262 type(vector_field), pointer :: positions
263 type(csr_matrix) :: timestepping_mat
232264
233 call c_f_pointer(context, matrices)265 call c_f_pointer(context, matrices)
234 266
@@ -240,6 +272,7 @@
240 u_mesh => extract_mesh(matrices, "VelocityMesh")272 u_mesh => extract_mesh(matrices, "VelocityMesh")
241 diffusion_mat => extract_csr_matrix(matrices, "DiffusionMatrix")273 diffusion_mat => extract_csr_matrix(matrices, "DiffusionMatrix")
242 mass_mat => extract_csr_matrix(matrices, "MassMatrix")274 mass_mat => extract_csr_matrix(matrices, "MassMatrix")
275 positions => extract_vector_field(matrices, "Coordinate")
243276
244 if (nvar==2) then277 if (nvar==2) then
245 if (variables(1)%timestep==variables(2)%timestep-1) then278 if (variables(1)%timestep==variables(2)%timestep-1) then
@@ -259,29 +292,45 @@
259 end if292 end if
260293
261 ! Ensure that the input velocity has indeed dirichlet bc attached294 ! Ensure that the input velocity has indeed dirichlet bc attached
262 ! Ensure that the input velocity has indeed dirichlet bc attached
263 if (get_boundary_condition_count(previous_u)==0) then295 if (get_boundary_condition_count(previous_u)==0) then
264 FLAbort("Velocity in callback must have dirichlet conditions attached")296 FLAbort("Velocity in callback must have dirichlet conditions attached")
265 end if297 end if
266298
267 call field_from_adj_vector(input, u_input)299 call field_from_adj_vector(input, u_input)
268 300
269 call allocate(u_output, u_mesh, "TimeSteppingAdjointVelocityOutput")301 call allocate(u_output, u_mesh, "TimeSteppingAdjointVelocityOutput")
270 call zero(u_output)302 call zero(u_output)
303 call allocate(tmp_u, u_mesh, "TimeSteppingAdjointVelocityOutput")
304 call zero(tmp_u)
271305
272 call allocate(timestepping_mat, mass_mat%sparsity, name="TimesteppingMatrix")306 call allocate(timestepping_mat, mass_mat%sparsity, name="TimesteppingMatrix")
273 call zero(timestepping_mat)307 call zero(timestepping_mat)
274308
275 if (.not. have_option(trim(adjoint_field_path('/material_phase::Fluid/scalar_field::Velocity/prognostic/temporal_discretisation/remove_time_term')))) then309 if (running_adjoint) then
276 call addto(timestepping_mat, mass_mat, scale=1.0/dt)310 path = adjoint_field_path("/material_phase::Fluid/scalar_field::Velocity")
277 end if311 else
278312 path = "/material_phase::Fluid/scalar_field::Velocity"
279! call mult(tmp, advection_mat, u_input)313 end if
280! call scale(tmp, theta - 1.0)314
281! call addto(u_output, tmp)315 if (.not. have_option(trim(path) // '/prognostic/temporal_discretisation/remove_time_term')) then
282316 call addto(timestepping_mat, mass_mat, scale=1.0/abs(dt))
283 call addto(timestepping_mat, diffusion_mat, scale=theta - 1.0)317 end if
284318
319 if (.not. have_option(trim(path) // '/prognostic/remove_advection_term')) then
320 call allocate(advection_mat, mass_mat%sparsity, name="BurgersCallbackAdvectionMatrix")
321 call zero(advection_mat)
322 call assemble_advection_matrix(advection_mat, positions, previous_u, iter_u)
323 call addto(timestepping_mat, advection_mat, scale=theta-1.0)
324 call deallocate(advection_mat)
325 end if
326
327 call addto(timestepping_mat, diffusion_mat, scale=theta-1.0)
328
329 call scale(timestepping_mat, -1.0)
330 if (get_boundary_condition_count(previous_u)==0) then
331 FLAbort("Velocity in callback must have dirichlet conditions attached")
332 end if
333 ! Mangle the dirichlet rows
285 call mangle_dirichlet_rows(timestepping_mat, previous_u, keep_diag=.false.)334 call mangle_dirichlet_rows(timestepping_mat, previous_u, keep_diag=.false.)
286335
287 if (hermitian==ADJ_FALSE) then336 if (hermitian==ADJ_FALSE) then
@@ -289,12 +338,283 @@
289 else338 else
290 call mult_T(u_output, timestepping_mat, u_input)339 call mult_T(u_output, timestepping_mat, u_input)
291 end if340 end if
341
342 call deallocate(timestepping_mat)
343
292 call scale(u_output, coefficient)344 call scale(u_output, coefficient)
293 output = field_to_adj_vector(u_output)345 output = field_to_adj_vector(u_output)
294 call deallocate(u_output)346 call deallocate(u_output)
295 call deallocate(timestepping_mat)347 call deallocate(tmp_u)
296 end subroutine timestepping_operator_action_callback348 end subroutine timestepping_operator_action_callback
297349
298350 subroutine advection_derivative_action_proc(nvar, variables, dependencies, derivative, contraction, hermitian, &
351 & input, coefficient, context, output) bind(c)
352 use iso_c_binding
353 use libadjoint_data_structures
354 use simple_advection_d
355 use simple_advection_b
356 integer(kind=c_int), intent(in), value :: nvar
357 type(adj_variable), dimension(nvar), intent(in) :: variables
358 type(adj_vector), dimension(nvar), intent(in) :: dependencies
359 type(adj_variable), intent(in), value :: derivative
360 type(adj_vector), intent(in), value :: contraction
361 integer(kind=c_int), intent(in), value :: hermitian
362 type(adj_vector), intent(in), value :: input
363 adj_scalar_f, intent(in), value :: coefficient
364 type(c_ptr), intent(in), value :: context
365 type(adj_vector), intent(out) :: output
366
367 type(state_type), pointer :: matrices
368 type(vector_field), pointer :: positions
369 type(scalar_field) :: u_left, u_right
370 type(scalar_field) :: contraction_field, udot, Acbar
371 type(scalar_field) :: output_field, tmp_field, u
372 character(len=OPTION_PATH_LEN) :: path
373
374 real :: itheta
375
376 assert(nvar == 1 .or. nvar == 2)
377 call c_f_pointer(context, matrices)
378 positions => extract_vector_field(matrices, "Coordinate")
379
380 call field_from_adj_vector(contraction, contraction_field)
381 call allocate(output_field, contraction_field%mesh, "NonlinearDerivativeOutput")
382 call zero(output_field)
383
384 if (have_option("/material_phase::Fluid/scalar_field::Velocity")) then
385 path = "/material_phase::Fluid/scalar_field::Velocity"
386 else
387 path = "/material_phase::Fluid/scalar_field::Velocity"
388 path = adjoint_field_path(path)
389 end if
390
391 if (hermitian == ADJ_FALSE) then
392 call field_from_adj_vector(input, udot)
393 call get_option(trim(path) // "/prognostic/temporal_discretisation/relaxation", itheta)
394 if (have_option(trim(path) // "/prognostic/remove_advection_term")) then
395 output = field_to_adj_vector(output_field)
396 call deallocate(output_field)
397 return
398 end if
399 else
400 call get_option(trim(path) // "/prognostic/temporal_discretisation/relaxation", itheta)
401 call field_from_adj_vector(input, Acbar)
402 if (have_option(trim(path) // "/prognostic/remove_advection_term")) then
403 output = field_to_adj_vector(output_field)
404 call deallocate(output_field)
405 return
406 end if
407 end if
408
409 call allocate(tmp_field, contraction_field%mesh, "TmpOutput")
410 call zero(tmp_field)
411
412 if (nvar == 1) then
413 call field_from_adj_vector(dependencies(1), u_left)
414 if (hermitian == ADJ_FALSE) then
415 call advection_action_d(positions%val(1,:), u_left%val, udot%val, contraction_field%val, tmp_field%val, output_field%val)
416 else
417 call advection_action_b(positions%val(1,:), u_left%val, output_field%val, contraction_field%val, tmp_field%val, Acbar%val)
418 end if
419 else if (nvar == 2) then
420 call field_from_adj_vector(dependencies(1), u_left)
421 call field_from_adj_vector(dependencies(2), u_right)
422 call allocate(u, u_left%mesh, "AdvectingVelocity")
423 call set(u, u_left)
424 call scale(u, (1.0-itheta))
425 call addto(u, u_right, scale=itheta)
426
427 if (hermitian == ADJ_FALSE) then
428 call advection_action_d(positions%val(1,:), u%val, udot%val, contraction_field%val, tmp_field%val, output_field%val)
429 else
430 call advection_action_b(positions%val(1,:), u%val, output_field%val, contraction_field%val, tmp_field%val, Acbar%val)
431 end if
432
433 call deallocate(u)
434
435 if (derivative == variables(1)) then
436 call scale(output_field, (1.0-itheta))
437 else if (derivative == variables(2)) then
438 call scale(output_field, itheta)
439 end if
440 end if
441
442 call deallocate(tmp_field)
443 call scale(output_field, coefficient)
444 output = field_to_adj_vector(output_field)
445 call deallocate(output_field)
446 end subroutine advection_derivative_action_proc
447
448 subroutine burgers_equation_forward_source(adjointer, var, ndepends, dependencies, values, context, output, has_output) bind(c)
449 type(adj_adjointer), intent(in) :: adjointer
450 type(adj_variable), intent(in), value :: var
451 integer(kind=c_int), intent(in), value :: ndepends
452 type(adj_variable), dimension(ndepends), intent(in) :: dependencies
453 type(adj_vector), dimension(ndepends), intent(in) :: values
454 type(c_ptr), intent(in), value :: context
455 type(adj_vector), intent(out) :: output
456 integer(kind=c_int), intent(out) :: has_output
457
458 character(len=ADJ_DICT_LEN) :: path
459 character(len=ADJ_NAME_LEN) :: name
460 integer :: timestep
461 real :: time, dt, end_time
462 real :: theta
463 type(state_type), pointer :: matrices
464 logical :: has_source
465 type(mesh_type), pointer :: u_mesh
466 type(state_type), dimension(1) :: dummy_state
467 type(scalar_field) :: u_output, tmp_u_output, dummy_u
468 type(csr_matrix), pointer :: mass_matrix
469 type(vector_field), pointer :: positions
470 type(csr_matrix) :: mangled_mass_matrix
471
472 integer :: ierr
473
474 ierr = adj_variable_get_name(var, name)
475 call adj_chkierr(ierr)
476
477 ierr = adj_variable_get_timestep(var, timestep)
478 call adj_chkierr(ierr)
479
480 call c_f_pointer(context, matrices)
481 assert(associated(matrices))
482 u_mesh => extract_mesh(matrices, "VelocityMesh")
483 positions => extract_vector_field(matrices, "Coordinate")
484 mass_matrix => extract_csr_matrix(matrices, "MassMatrix")
485
486 path = "/material_phase::Fluid/scalar_field::Velocity"
487
488 has_source = have_option(trim(path) // "/prognostic/scalar_field::Source")
489
490 if (timestep == 0) then ! initial condition
491 call allocate(u_output, u_mesh, "VelocityInitialCondition")
492 call zero(u_output)
493 u_output%option_path = trim(path)
494 call insert(dummy_state(1), positions, "Coordinate")
495 call insert(dummy_state(1), u_output, "Velocity")
496 call initialise_prognostic_fields(dummy_state)
497
498 ! Set initial condition
499 call populate_boundary_conditions(dummy_state)
500 call set_boundary_conditions_values(dummy_state, shift_time=.false.)
501 call set_dirichlet_consistent(dummy_state)
502 call deallocate(dummy_state(1))
503
504 output = field_to_adj_vector(u_output)
505 has_output = ADJ_TRUE
506 call deallocate(u_output)
507 else if (timestep > 0) then
508 if (.not. has_source) then
509 has_output = ADJ_FALSE
510 else
511 call allocate(tmp_u_output, u_mesh, "VelocitySource")
512 call allocate(u_output, u_mesh, "VelocitySource")
513 call allocate(dummy_u, u_mesh, "DummyVelocity")
514 call zero(tmp_u_output)
515 call zero(u_output)
516 tmp_u_output%option_path = trim(path) // "/prognostic/scalar_field::Source"
517 dummy_u%option_path = trim(path)
518
519 call insert(dummy_state(1), positions, "Coordinate")
520 call insert(dummy_state(1), tmp_u_output, "VelocitySource")
521 call insert(dummy_state(1), dummy_u, "DummyVelocity")
522
523 call populate_boundary_conditions(dummy_state)
524
525 ierr = adj_timestep_get_times(adjointer, timestep-1, time, end_time)
526 call adj_chkierr(ierr)
527 dt = end_time - time
528
529 call get_option(trim(path) // "/prognostic/temporal_discretisation/theta", theta, default=0.5)
530 call set_prescribed_field_values(dummy_state, time=time + theta*abs(dt))
531 call deallocate(dummy_state(1))
532
533 call allocate(mangled_mass_matrix, mass_matrix%sparsity, name="MangledMassMatrix")
534 call set(mangled_mass_matrix, mass_matrix)
535 call mangle_dirichlet_rows(mangled_mass_matrix, dummy_u, keep_diag=.false.)
536 call mult(u_output, mangled_mass_matrix, tmp_u_output)
537 call deallocate(mangled_mass_matrix)
538
539 call deallocate(tmp_u_output)
540 call deallocate(dummy_u)
541
542 output = field_to_adj_vector(u_output)
543 has_output = ADJ_TRUE
544 call deallocate(u_output)
545 end if
546 end if
547
548 end subroutine burgers_equation_forward_source
549
550 subroutine advection_action_proc(nvar, variables, dependencies, input, context, output) bind(c)
551 use iso_c_binding
552 use libadjoint_data_structures
553 use simple_advection
554 integer(kind=c_int), intent(in), value :: nvar
555 type(adj_variable), dimension(nvar), intent(in) :: variables
556 type(adj_vector), dimension(nvar), intent(in) :: dependencies
557 type(adj_vector), intent(in), value :: input
558 type(c_ptr), intent(in), value :: context
559 type(adj_vector), intent(out) :: output
560
561 type(scalar_field) :: u_output, u_check, nonlinear_u
562 type(scalar_field) :: previous_u, iter_u, u_input
563 type(csr_matrix) :: advection_mat
564 type(csr_matrix), pointer :: diffusion_mat
565 type(vector_field), pointer :: positions
566 type(mesh_type), pointer :: u_mesh
567 type(state_type), pointer :: matrices
568 character(len=OPTION_PATH_LEN) :: path
569 real :: itheta
570
571 path = "/material_phase::Fluid/scalar_field::Velocity"
572 if (running_adjoint) then
573 path = adjoint_field_path(path)
574 end if
575
576 if (nvar==2) then
577 if (variables(1)%timestep==variables(2)%timestep-1) then
578 call field_from_adj_vector(dependencies(1), previous_u)
579 call field_from_adj_vector(dependencies(2), iter_u)
580 else if(variables(2)%timestep==variables(1)%timestep-1) then
581 call field_from_adj_vector(dependencies(2), previous_u)
582 call field_from_adj_vector(dependencies(1), iter_u)
583 else
584 FLAbort("Dependencies have no contiguous timesteps.")
585 end if
586 else if (nvar==1) then
587 call field_from_adj_vector(dependencies(1), previous_u)
588 call field_from_adj_vector(dependencies(1), iter_u)
589 else
590 FLAbort("Unknown number of dependencies in burgers_operator_assembly_callback")
591 end if
592
593 call field_from_adj_vector(input, u_input)
594
595 call c_f_pointer(context, matrices)
596 u_mesh => extract_mesh(matrices, "VelocityMesh")
597 diffusion_mat => extract_csr_matrix(matrices, "DiffusionMatrix")
598 positions => extract_vector_field(matrices, "Coordinate")
599
600 call allocate(advection_mat, diffusion_mat%sparsity, name="AdvectionActionMatrix")
601 call zero(advection_mat)
602 if (.not. have_option(trim(path) // "/prognostic/remove_advection_term")) then
603 call assemble_advection_matrix(advection_mat, positions, previous_u, iter_u)
604 end if
605
606 if (get_boundary_condition_count(previous_u) /= 1) then
607 FLAbort("Need to supply boundary conditions on previous_u")
608 end if
609
610 call mangle_dirichlet_rows(advection_mat, previous_u, keep_diag=.true.)
611
612 call allocate(u_output, u_mesh, "AdvectionActionOutput")
613 call mult(u_output, advection_mat, u_input)
614 call deallocate(advection_mat)
615
616 output = field_to_adj_vector(u_output)
617 call deallocate(u_output)
618 end subroutine advection_action_proc
299#endif619#endif
300end module burgers_adjoint_callbacks620end module burgers_adjoint_callbacks
301621
=== added file 'adjoint/Burgers_Control_Callbacks.F90'
--- adjoint/Burgers_Control_Callbacks.F90 1970-01-01 00:00:00 +0000
+++ adjoint/Burgers_Control_Callbacks.F90 2011-07-12 15:56:32 +0000
@@ -0,0 +1,183 @@
1! Copyright (C) 2006 Imperial College London and others.
2!
3! Please see the AUTHORS file in the main source directory for a full list
4! of copyright holders.
5!
6! Prof. C Pain
7! Applied Modelling and Computation Group
8! Department of Earth Science and Engineering
9! Imperial College London
10!
11! amcgsoftware@imperial.ac.uk
12!
13! This library is free software; you can redistribute it and/or
14! modify it under the terms of the GNU Lesser General Public
15! License as published by the Free Software Foundation,
16! version 2.1 of the License.
17!
18! This library is distributed in the hope that it will be useful,
19! but WITHOUT ANY WARRANTY; without even the implied warranty of
20! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21! Lesser General Public License for more details.
22!
23! You should have received a copy of the GNU Lesser General Public
24! License along with this library; if not, write to the Free Software
25! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26! USA
27
28#include "fdebug.h"
29
30module burgers_adjoint_controls
31 use fields
32 use global_parameters, only : PYTHON_FUNC_LEN, OPTION_PATH_LEN
33 use spud
34 use state_module
35 use python_state
36 use sparse_matrices_fields
37 use manifold_projections
38 use mangle_dirichlet_rows_module
39
40 implicit none
41
42 private
43
44 public :: burgers_adjoint_timestep_callback
45
46 contains
47
48 ! Data is a void pointer used to pass variables into the callback
49 subroutine burgers_adjoint_timestep_callback(states, timestep, functional_name, data)
50 use iso_c_binding, only: c_ptr
51 use global_parameters, only: OPTION_PATH_LEN
52 use state_module
53 type(state_type), dimension(:), intent(inout) :: states
54 integer, intent(in) :: timestep
55 character(len=*), intent(in) :: functional_name
56 type(c_ptr), intent(in) :: data
57
58 type(state_type), pointer :: matrices
59 character(len=OPTION_PATH_LEN) :: field_name, control_type, control_deriv_name, field_deriv_name, name, material_phase_name
60 integer :: nb_controls
61 integer :: i, state_id, s_idx
62 type(scalar_field), pointer :: sfield, adj_sfield, adj_sfield2
63 type(vector_field), pointer :: vfield, adj_vfield, positions
64 type(tensor_field), pointer :: tfield, adj_tfield
65 type(block_csr_matrix), pointer :: big_mat, div_mat, u_mass_mat
66 type(csr_matrix), pointer :: h_mass_mat
67 type(csr_matrix) :: h_mangled_mass_mat
68 type(state_type), dimension(1) :: dummy_state
69
70 type(scalar_field) :: dummy_u
71 type(vector_field) :: local_src_tmp, local_src_tmp2, src_tmp
72 real :: theta, d0, dt
73 integer :: stat
74
75 ! Cast the data to the matrices state
76 call c_f_pointer(data, matrices)
77
78
79 nb_controls = option_count("/adjoint/controls/control")
80 do i = 0, nb_controls-1
81 call get_option("/adjoint/controls/control[" // int2str(i) //"]/name", control_deriv_name)
82 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type/name", control_type)
83 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type::" // trim(control_type) // "/field_name", name)
84 s_idx = scan(trim(name), "::")
85 if (s_idx == 0) then
86 FLAbort("The control " // trim(control_deriv_name) // " uses an invalid field_name. It should be of the form Materialphase::Fieldname")
87 end if
88 material_phase_name = name(1:s_idx - 1)
89 field_name = name(s_idx + 2:len_trim(name))
90 ! Find state associated with the material phase
91 do state_id = 1, size(states)
92 if (trim(states(state_id)%name) == trim(material_phase_name)) then
93 exit
94 end if
95 end do
96 ! Make sure we found the state
97 if (.not. trim(states(state_id)%name) == trim(material_phase_name)) then
98 FLAbort("Could not find state " // trim(material_phase_name) // " as specified in control " // trim(control_deriv_name) // ".")
99 end if
100
101 control_deriv_name = trim(control_deriv_name) // "_TotalDerivative"
102 select case(trim(control_type))
103
104 !!!!!!!!!!!!! Initial condition !!!!!!!!!!!!
105 case ("initial_condition")
106 if (timestep /= 0) then
107 cycle
108 end if
109 field_deriv_name = trim(functional_name) // "_" // control_deriv_name
110 if (has_scalar_field(states(state_id), field_deriv_name)) then
111 if (trim(field_name) == "Velocity") then
112 adj_sfield => extract_scalar_field(states(state_id), "Adjoint" // trim(field_name))
113 sfield => extract_scalar_field(states(state_id), field_deriv_name) ! Output field
114 positions => extract_vector_field(matrices, "Coordinate")
115 call set(sfield, adj_sfield)
116
117 ! Populate boundary conditions
118 call allocate(dummy_u, adj_sfield%mesh, "DummyVelocity")
119 dummy_u%option_path = "/material_phase::Fluid/scalar_field::AdjointVelocity"
120 call insert(dummy_state(1), positions, "Coordinate")
121 call insert(dummy_state(1), dummy_u, "AdjointVelocity")
122 call populate_boundary_conditions(dummy_state)
123
124 ! Now we need to zero the derivative field everywhere we have Dirichlet conditions
125 call mangle_dirichlet_rows(sfield, dummy_u)
126
127 call deallocate(dummy_u)
128 call deallocate(dummy_state(1))
129 else
130 FLAbort("Sorry, I do not know how to compute the intial condition control for " // trim(field_name) // ".")
131 end if
132 else
133 FLAbort("The control derivative field " // trim(field_deriv_name) // " specified for " // trim(control_deriv_name) // " is not a field in the state.")
134 end if
135
136 !!!!!!!!!!!!! Boundary condition !!!!!!!!!!!!
137 case("boundary_condition")
138 FLAbort("Boundary condition control not implemented yet.")
139
140 !!!!!!!!!!!!! Source !!!!!!!!!!!!
141 case("source_term")
142 field_deriv_name = trim(functional_name) // "_" // control_deriv_name
143 sfield => extract_scalar_field(states(state_id), field_deriv_name, stat=stat) ! Output field
144 if (stat /= 0) then
145 FLAbort("The control derivative field " // trim(field_deriv_name) // " specified for " // trim(control_deriv_name) // " is not a field in the state.")
146 end if
147
148 if (timestep == 0) then
149 call zero(sfield)
150 else
151 if (trim(field_name) == "VelocitySource") then
152 adj_sfield => extract_scalar_field(states(state_id), "AdjointVelocity")
153 h_mass_mat => extract_csr_matrix(matrices, "MassMatrix")
154 positions => extract_vector_field(matrices, "Coordinate")
155
156 ! Populate boundary conditions
157 call allocate(dummy_u, adj_sfield%mesh, "DummyVelocity")
158 dummy_u%option_path = "/material_phase::Fluid/scalar_field::AdjointVelocity"
159 call insert(dummy_state(1), positions, "Coordinate")
160 call insert(dummy_state(1), dummy_u, "AdjointVelocity")
161 call populate_boundary_conditions(dummy_state)
162
163 ! Mangle the mass matrix
164 call allocate(h_mangled_mass_mat, h_mass_mat%sparsity, name="MangledMassMatrix")
165 call set(h_mangled_mass_mat, h_mass_mat)
166 call mangle_dirichlet_rows(h_mangled_mass_mat, dummy_u, keep_diag=.false.)
167 call mult_T(sfield, h_mangled_mass_mat, adj_sfield)
168
169 ! Deallocate temporary variables
170 call deallocate(dummy_state(1))
171 call deallocate(dummy_u)
172 call deallocate(h_mangled_mass_mat)
173
174 else
175 FLAbort("Sorry, I do not know how to compute the source condition control for " // trim(field_name) // ".")
176 end if
177 end if
178 end select
179 end do
180
181 end subroutine burgers_adjoint_timestep_callback
182
183end module burgers_adjoint_controls
0184
=== modified file 'adjoint/Forward_Main_Loop.F90'
--- adjoint/Forward_Main_Loop.F90 2011-05-13 17:52:57 +0000
+++ adjoint/Forward_Main_Loop.F90 2011-07-12 15:56:32 +0000
@@ -40,6 +40,7 @@
40 use adjoint_global_variables40 use adjoint_global_variables
41 use adjoint_functional_evaluation41 use adjoint_functional_evaluation
42 use populate_state_module42 use populate_state_module
43 use boundary_conditions_from_options
43 use signal_vars44 use signal_vars
44 use mangle_options_tree45 use mangle_options_tree
45 use mangle_dirichlet_rows_module46 use mangle_dirichlet_rows_module
@@ -53,12 +54,13 @@
53 implicit none54 implicit none
5455
55 private56 private
57 public :: forward_main_loop_register_diagnostic
56#ifdef HAVE_ADJOINT58#ifdef HAVE_ADJOINT
57 public :: compute_forward59 public :: compute_forward, calculate_functional_values, register_functional_callbacks
58#endif60#endif
5961
60#ifdef HAVE_ADJOINT
61 contains62 contains
63#ifdef HAVE_ADJOINT
6264
63 subroutine compute_forward(state)65 subroutine compute_forward(state)
64 type(state_type), dimension(:), intent(inout) :: state66 type(state_type), dimension(:), intent(inout) :: state
@@ -153,6 +155,11 @@
153155
154 if (has_path) then156 if (has_path) then
155 sfield_soln%option_path = trim(path)157 sfield_soln%option_path = trim(path)
158 ! We need to populate the BC values:
159 call insert(state(1), sfield_soln, trim(sfield_soln%name))
160 call populate_boundary_conditions(state)
161 call set_boundary_conditions_values(state, shift_time=.false.)
162 sfield_soln = extract_scalar_field(state(1), trim(sfield_soln%name))
156 end if163 end if
157164
158 select case(lhs%klass)165 select case(lhs%klass)
@@ -168,6 +175,10 @@
168 call adj_chkierr(ierr)175 call adj_chkierr(ierr)
169 end if176 end if
170177
178 sfield_rhs%bc => sfield_soln%bc
179 call set_dirichlet_consistent(sfield_rhs)
180 sfield_rhs%bc => null()
181
171 call petsc_solve(sfield_soln, csr_mat, sfield_rhs, option_path=path)182 call petsc_solve(sfield_soln, csr_mat, sfield_rhs, option_path=path)
172 call compute_inactive_rows(sfield_soln, csr_mat, sfield_rhs)183 call compute_inactive_rows(sfield_soln, csr_mat, sfield_rhs)
173 endif184 endif
@@ -178,6 +189,7 @@
178 end select189 end select
179190
180 call insert(state(1), sfield_soln, trim(sfield_soln%name))191 call insert(state(1), sfield_soln, trim(sfield_soln%name))
192
181 soln = field_to_adj_vector(sfield_soln)193 soln = field_to_adj_vector(sfield_soln)
182 ierr = adj_storage_memory_incref(soln, storage)194 ierr = adj_storage_memory_incref(soln, storage)
183 call adj_chkierr(ierr)195 call adj_chkierr(ierr)
@@ -197,6 +209,11 @@
197209
198 if (has_path) then210 if (has_path) then
199 vfield_soln%option_path = trim(path)211 vfield_soln%option_path = trim(path)
212 ! We need to populate the BC values:
213 call insert(state(1), vfield_soln, trim(vfield_soln%name))
214 call populate_boundary_conditions(state)
215 call set_boundary_conditions_values(state, shift_time=.false.)
216 vfield_soln = extract_vector_field(state(1), trim(vfield_soln%name))
200 end if217 end if
201218
202 select case(lhs%klass)219 select case(lhs%klass)
@@ -212,6 +229,10 @@
212 call adj_chkierr(ierr)229 call adj_chkierr(ierr)
213 end if230 end if
214231
232 vfield_rhs%bc => vfield_soln%bc
233 call set_dirichlet_consistent(vfield_rhs)
234 vfield_rhs%bc => null()
235
215 call petsc_solve(vfield_soln, csr_mat, vfield_rhs, option_path=path)236 call petsc_solve(vfield_soln, csr_mat, vfield_rhs, option_path=path)
216 !call compute_inactive_rows(vfield_soln, csr_mat, vfield_rhs)237 !call compute_inactive_rows(vfield_soln, csr_mat, vfield_rhs)
217 endif238 endif
@@ -233,6 +254,7 @@
233 end select254 end select
234255
235 call insert(state(1), vfield_soln, trim(vfield_soln%name))256 call insert(state(1), vfield_soln, trim(vfield_soln%name))
257
236 soln = field_to_adj_vector(vfield_soln)258 soln = field_to_adj_vector(vfield_soln)
237 ierr = adj_storage_memory_incref(soln, storage)259 ierr = adj_storage_memory_incref(soln, storage)
238 call adj_chkierr(ierr)260 call adj_chkierr(ierr)
@@ -264,8 +286,17 @@
264 call set_prescribed_field_values(state, exclude_interpolated=.true., exclude_nonreprescribed=.true., time=current_time)286 call set_prescribed_field_values(state, exclude_interpolated=.true., exclude_nonreprescribed=.true., time=current_time)
265 call calculate_diagnostic_variables(state, exclude_nonrecalculated = .true.)287 call calculate_diagnostic_variables(state, exclude_nonrecalculated = .true.)
266 call calculate_diagnostic_variables_new(state, exclude_nonrecalculated = .true.)288 call calculate_diagnostic_variables_new(state, exclude_nonrecalculated = .true.)
289 ! The first timestep is the initialisation of the model.
290 ! We skip the evaluation of the functional at timestep zero to get the correct value.
291 if (timestep > 0) then
292 call calculate_functional_values(timestep-1)
293 ! The last timestep is a the dummy timestep added at the end to act
294 ! as a container for the last equation
295 if (start_time == end_time) then
296 assert(timestep == no_timesteps-1)
297 end if
298 end if
267 call write_diagnostics(state, current_time, dt, equation+1)299 call write_diagnostics(state, current_time, dt, equation+1)
268
269 if (do_write_state(current_time, timestep)) then300 if (do_write_state(current_time, timestep)) then
270 call write_state(dump_no, state)301 call write_state(dump_no, state)
271 endif302 endif
@@ -286,5 +317,69 @@
286 call get_option("/timestepping/finish_time", finish_time)317 call get_option("/timestepping/finish_time", finish_time)
287 assert(current_time == finish_time)318 assert(current_time == finish_time)
288 end subroutine compute_forward319 end subroutine compute_forward
289#endif320
321 subroutine register_functional_callbacks()
322 integer :: no_functionals, functional
323 character(len=ADJ_NAME_LEN) :: functional_name
324 integer :: ierr
325
326 no_functionals = option_count("/adjoint/functional")
327 do functional=0,no_functionals-1
328 if (have_option("/adjoint/functional[" // int2str(functional) // "]/functional_value")) then
329 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
330 ! Register the callback to compute J
331 ierr = adj_register_functional_callback(adjointer, trim(functional_name), c_funloc(libadjoint_evaluate_functional))
332 call adj_chkierr(ierr)
333 end if
334 end do
335 end subroutine register_functional_callbacks
336
337 subroutine calculate_functional_values(timestep)
338 integer, intent(in) :: timestep
339 integer :: functional, no_functionals
340 character(len=OPTION_PATH_LEN) :: functional_name
341 real, dimension(:), pointer :: fn_value
342 real :: J
343 integer :: ierr
344
345 no_functionals = option_count("/adjoint/functional")
346 do functional=0,no_functionals-1
347 if (have_option("/adjoint/functional[" // int2str(functional) // "]/functional_value")) then
348 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
349 ierr = adj_evaluate_functional(adjointer, timestep, functional_name, J)
350 call adj_chkierr(ierr)
351 ! So we've computed the component of the functional associated with this timestep.
352 ! We also want to sum them all up ...
353 call set_diagnostic(name=trim(functional_name) // "_component", statistic="value", value=(/J/))
354 fn_value => get_diagnostic(name=trim(functional_name), statistic="value")
355 J = J + fn_value(1)
356 call set_diagnostic(name=trim(functional_name), statistic="value", value=(/J/))
357 end if
358 end do
359 end subroutine calculate_functional_values
360
361#endif
362
363 ! Register a diagnostic variable for each functional.
364 subroutine forward_main_loop_register_diagnostic
365 integer :: functional, no_functionals
366 character(len=OPTION_PATH_LEN) :: functional_name
367
368#ifdef HAVE_ADJOINT
369 no_functionals = option_count("/adjoint/functional")
370
371 do functional=0,no_functionals-1
372 ! Register a diagnostic for each functional
373 if (have_option("/adjoint/functional[" // int2str(functional) // "]/functional_value")) then
374 call get_option("/adjoint/functional[" // int2str(functional) // "]/name", functional_name)
375 call register_diagnostic(dim=1, name=trim(functional_name) // "_component", statistic="value")
376 call register_diagnostic(dim=1, name=trim(functional_name), statistic="value")
377 ! The functional value will be accumulated, so initialise it with zero.
378 call set_diagnostic(name=trim(functional_name) // "_component", statistic="value", value=(/0.0/))
379 call set_diagnostic(name=trim(functional_name), statistic="value", value=(/0.0/))
380 end if
381 end do
382#endif
383 end subroutine forward_main_loop_register_diagnostic
384
290end module forward_main_loop385end module forward_main_loop
291386
=== modified file 'adjoint/Libadjoint_Data_Callbacks.F90'
--- adjoint/Libadjoint_Data_Callbacks.F90 2011-05-24 10:42:33 +0000
+++ adjoint/Libadjoint_Data_Callbacks.F90 2011-07-12 15:56:32 +0000
@@ -88,6 +88,8 @@
88 call adj_chkierr(ierr)88 call adj_chkierr(ierr)
89 ierr = adj_register_data_callback(adjointer, ADJ_VEC_GET_NORM_CB, c_funloc(femtools_vec_getnorm_proc))89 ierr = adj_register_data_callback(adjointer, ADJ_VEC_GET_NORM_CB, c_funloc(femtools_vec_getnorm_proc))
90 call adj_chkierr(ierr)90 call adj_chkierr(ierr)
91 ierr = adj_register_data_callback(adjointer, ADJ_VEC_GET_SIZE_CB, c_funloc(femtools_vec_get_size_proc))
92 call adj_chkierr(ierr)
91 ierr = adj_register_data_callback(adjointer, ADJ_VEC_DOT_PRODUCT_CB, c_funloc(femtools_vec_dot_product_proc))93 ierr = adj_register_data_callback(adjointer, ADJ_VEC_DOT_PRODUCT_CB, c_funloc(femtools_vec_dot_product_proc))
92 call adj_chkierr(ierr)94 call adj_chkierr(ierr)
93 ierr = adj_register_data_callback(adjointer, ADJ_VEC_SET_RANDOM_CB, c_funloc(femtools_vec_set_random_proc))95 ierr = adj_register_data_callback(adjointer, ADJ_VEC_SET_RANDOM_CB, c_funloc(femtools_vec_set_random_proc))
@@ -317,6 +319,27 @@
317 end if319 end if
318 end subroutine femtools_vec_set_random_proc320 end subroutine femtools_vec_set_random_proc
319321
322 subroutine femtools_vec_get_size_proc(vec, sz) bind(c)
323 type(adj_vector), intent(in), value :: vec
324 integer(kind=c_int), intent(out) :: sz
325 type(scalar_field), pointer :: scalar
326 type(vector_field), pointer :: vector
327 type(tensor_field), pointer :: tensor
328
329 if (vec%klass == ADJ_SCALAR_FIELD) then
330 call c_f_pointer(vec%ptr, scalar)
331 sz = node_count(scalar)
332 else if (vec%klass == ADJ_VECTOR_FIELD) then
333 call c_f_pointer(vec%ptr, vector)
334 sz = node_count(vector) * vector%dim
335 else if (vec%klass == ADJ_TENSOR_FIELD) then
336 call c_f_pointer(vec%ptr, tensor)
337 sz = node_count(tensor) * tensor%dim(1) * tensor%dim(2)
338 else
339 FLAbort("adj_vector class not supported.")
340 end if
341 end subroutine femtools_vec_get_size_proc
342
320 subroutine femtools_mat_axpy_proc(Y, alpha, X) bind(c) 343 subroutine femtools_mat_axpy_proc(Y, alpha, X) bind(c)
321 ! Computes Y = alpha*X + Y.344 ! Computes Y = alpha*X + Y.
322 use iso_c_binding345 use iso_c_binding
323346
=== modified file 'adjoint/Makefile.dependencies'
--- adjoint/Makefile.dependencies 2011-05-23 14:44:04 +0000
+++ adjoint/Makefile.dependencies 2011-07-12 15:56:32 +0000
@@ -1,4 +1,12 @@
1# Dependencies generated by create_makefile.py. DO NOT EDIT1# Dependencies generated by create_makefile.py. DO NOT EDIT
2../include/adjoint_controls.mod: Adjoint_Controls.o
3 @true
4
5Adjoint_Controls.o ../include/adjoint_controls.mod: Adjoint_Controls.F90 \
6 ../include/boundary_conditions.mod ../include/global_parameters.mod \
7 ../include/fields.mod ../include/spud.mod ../include/python_state.mod \
8 ../include/fdebug.h ../include/state_module.mod
9
2../include/adjoint_functional_evaluation.mod: Adjoint_Functional_Evaluation.o10../include/adjoint_functional_evaluation.mod: Adjoint_Functional_Evaluation.o
3 @true11 @true
412
@@ -22,7 +30,7 @@
2230
23Adjoint_Main_Loop.o ../include/adjoint_main_loop.mod: Adjoint_Main_Loop.F90 \31Adjoint_Main_Loop.o ../include/adjoint_main_loop.mod: Adjoint_Main_Loop.F90 \
24 ../include/populate_state_module.mod ../include/sparse_matrices_fields.mod \32 ../include/populate_state_module.mod ../include/sparse_matrices_fields.mod \
25 ../include/diagnostic_fields_new.mod \33 ../include/diagnostic_fields_new.mod ../include/adjoint_controls.mod \
26 ../include/adjoint_functional_evaluation.mod ../include/sparse_tools.mod \34 ../include/adjoint_functional_evaluation.mod ../include/sparse_tools.mod \
27 ../include/fields.mod ../include/diagnostic_variables.mod \35 ../include/fields.mod ../include/diagnostic_variables.mod \
28 ../include/mangle_options_tree.mod ../include/write_state_module.mod \36 ../include/mangle_options_tree.mod ../include/write_state_module.mod \
@@ -44,12 +52,25 @@
4452
45Burgers_Adjoint_Callbacks.o ../include/burgers_adjoint_callbacks.mod: \53Burgers_Adjoint_Callbacks.o ../include/burgers_adjoint_callbacks.mod: \
46 Burgers_Adjoint_Callbacks.F90 ../include/libadjoint_data_callbacks.mod \54 Burgers_Adjoint_Callbacks.F90 ../include/libadjoint_data_callbacks.mod \
47 ../include/adjoint_global_variables.mod ../include/fields.mod \55 ../include/simple_advection.mod ../include/burgers_assembly.mod \
48 ../include/spud.mod ../include/mangle_options_tree.mod \56 ../include/populate_state_module.mod \
49 ../include/sparse_matrices_fields.mod \57 ../include/adjoint_global_variables.mod ../include/global_parameters.mod \
50 ../include/mangle_dirichlet_rows_module.mod ../include/fdebug.h \58 ../include/fields.mod ../include/simple_advection_b.mod ../include/spud.mod \
59 ../include/mangle_options_tree.mod ../include/sparse_matrices_fields.mod \
60 ../include/mangle_dirichlet_rows_module.mod \
61 ../include/simple_advection_d.mod ../include/fdebug.h \
51 ../include/state_module.mod62 ../include/state_module.mod
5263
64../include/burgers_adjoint_controls.mod: Burgers_Control_Callbacks.o
65 @true
66
67Burgers_Control_Callbacks.o ../include/burgers_adjoint_controls.mod: \
68 Burgers_Control_Callbacks.F90 ../include/mangle_dirichlet_rows_module.mod \
69 ../include/manifold_projections.mod ../include/global_parameters.mod \
70 ../include/fields.mod ../include/spud.mod \
71 ../include/sparse_matrices_fields.mod ../include/state_module.mod \
72 ../include/python_state.mod ../include/fdebug.h
73
53../include/forward_main_loop.mod: Forward_Main_Loop.o74../include/forward_main_loop.mod: Forward_Main_Loop.o
54 @true75 @true
5576
@@ -58,6 +79,7 @@
58 ../include/diagnostic_fields_new.mod \79 ../include/diagnostic_fields_new.mod \
59 ../include/adjoint_functional_evaluation.mod ../include/sparse_tools.mod \80 ../include/adjoint_functional_evaluation.mod ../include/sparse_tools.mod \
60 ../include/fields.mod ../include/diagnostic_variables.mod \81 ../include/fields.mod ../include/diagnostic_variables.mod \
82 ../include/boundary_conditions_from_options.mod \
61 ../include/mangle_options_tree.mod ../include/write_state_module.mod \83 ../include/mangle_options_tree.mod ../include/write_state_module.mod \
62 ../include/spud.mod ../include/mangle_dirichlet_rows_module.mod \84 ../include/spud.mod ../include/mangle_dirichlet_rows_module.mod \
63 ../include/state_module.mod ../include/libadjoint_data_callbacks.mod \85 ../include/state_module.mod ../include/libadjoint_data_callbacks.mod \
@@ -105,3 +127,14 @@
105 ../include/manifold_projections.mod ../include/fdebug.h \127 ../include/manifold_projections.mod ../include/fdebug.h \
106 ../include/state_module.mod128 ../include/state_module.mod
107129
130../include/shallow_water_adjoint_controls.mod: \
131 Shallow_Water_Control_Callbacks.o
132 @true
133
134Shallow_Water_Control_Callbacks.o \
135 ../include/shallow_water_adjoint_controls.mod: \
136 Shallow_Water_Control_Callbacks.F90 ../include/manifold_projections.mod \
137 ../include/global_parameters.mod ../include/fields.mod ../include/spud.mod \
138 ../include/sparse_matrices_fields.mod ../include/python_state.mod \
139 ../include/fdebug.h ../include/state_module.mod
140
108141
=== modified file 'adjoint/Makefile.in'
--- adjoint/Makefile.in 2011-05-19 14:29:56 +0000
+++ adjoint/Makefile.in 2011-07-12 15:56:32 +0000
@@ -43,10 +43,16 @@
4343
44LIB = ../lib/lib@FLUIDITY@.a44LIB = ../lib/lib@FLUIDITY@.a
4545
46OBJS = $(patsubst %.F90,%.o,$(wildcard *.F90)) $(patsubst %.c,%.o,$(wildcard *.c))46OBJS = $(patsubst %.F90,%.o,$(wildcard *.F90)) $(patsubst %.f90,%.o,$(wildcard *.f90)) $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.f,%.o,$(wildcard *.f))
4747
48.SUFFIXES: .F90 .c .cpp .o .a48.SUFFIXES: .f .f90 .F90 .c .cpp .o .a
4949
50.f90.o:
51 @echo " FC $<"
52 $(FC) $(FCFLAGS) $(GENFLAGS) -c $<
53.f.o:
54 @echo " FC $<"
55 $(FC) $(FCFLAGS) $(GENFLAGS) -c $<
50.F90.o:56.F90.o:
51 @echo " FC $<"57 @echo " FC $<"
52 $(FC) $(FCFLAGS) $(GENFLAGS) -c $< 58 $(FC) $(FCFLAGS) $(GENFLAGS) -c $<
@@ -71,4 +77,16 @@
71clean:77clean:
72 rm -f *.o *.d *.mod78 rm -f *.o *.d *.mod
7379
80# Instructions for doing AD with tapenade
81reverse:
82 tapenade -b -head "advection_action" -outvars "ac" -vars "u" simple_advection.f90 -ext PUSHPOPGeneralLib -extAD PUSHPOPADLib-fixinterface
83 echo "Don't forget to remove the zeroing of acb."
84
85forward:
86 tapenade -d -head "advection_action" -outvars "ac" -vars "u" simple_advection.f90
87
88../include/simple_advection.mod: simple_advection.o
89../include/simple_advection_d.mod: simple_advection_d.o
90../include/simple_advection_b.mod: simple_advection_b.o
91
74include Makefile.dependencies92include Makefile.dependencies
7593
=== modified file 'adjoint/Mangle_Dirichlet_Rows_Module.F90'
--- adjoint/Mangle_Dirichlet_Rows_Module.F90 2011-03-31 17:44:57 +0000
+++ adjoint/Mangle_Dirichlet_Rows_Module.F90 2011-07-12 15:56:32 +0000
@@ -35,7 +35,7 @@
35 implicit none35 implicit none
3636
37 interface mangle_dirichlet_rows37 interface mangle_dirichlet_rows
38 module procedure mangle_dirichlet_rows_csr_scalar38 module procedure mangle_dirichlet_rows_csr_scalar, mangle_dirichlet_rows_scalar
39 end interface39 end interface
4040
41 interface set_inactive_rows41 interface set_inactive_rows
@@ -90,6 +90,28 @@
90 end do90 end do
91 end subroutine mangle_dirichlet_rows_csr_scalar91 end subroutine mangle_dirichlet_rows_csr_scalar
9292
93 subroutine mangle_dirichlet_rows_scalar(scalar, bc_field)
94 type(scalar_field), intent(inout) :: scalar
95 type(scalar_field), intent(in) :: bc_field
96
97 integer :: i, j, node
98 character(len=FIELD_NAME_LEN) :: bctype
99 integer, dimension(:), pointer :: node_list
100
101 assert(node_count(scalar) == node_count(bc_field))
102
103 do i=1,get_boundary_condition_count(bc_field)
104 call get_boundary_condition(bc_field, i, type=bctype, surface_node_list=node_list)
105
106 if (bctype /= "dirichlet") cycle
107
108 do j=1,size(node_list)
109 node = node_list(j)
110 call set(scalar, node, 0.0)
111 end do
112 end do
113 end subroutine mangle_dirichlet_rows_scalar
114
93 subroutine set_inactive_rows_csr_scalar(matrix, field)115 subroutine set_inactive_rows_csr_scalar(matrix, field)
94 ! Any nodes associated with Dirichlet BCs, we make them inactive116 ! Any nodes associated with Dirichlet BCs, we make them inactive
95 type(csr_matrix), intent(inout) :: matrix117 type(csr_matrix), intent(inout) :: matrix
96118
=== modified file 'adjoint/Mangle_Options_Tree.F90'
--- adjoint/Mangle_Options_Tree.F90 2011-03-10 10:07:19 +0000
+++ adjoint/Mangle_Options_Tree.F90 2011-07-12 15:56:32 +0000
@@ -139,12 +139,6 @@
139 deallocate(fields_to_delete)139 deallocate(fields_to_delete)
140 end do140 end do
141141
142 ! We delete this because if it exists in the forward run,
143 ! write_diagnostics wants to print it out in the stat file.
144 do functional=0,option_count("/adjoint/functional")-1
145 call delete_option("/adjoint/functional[" // int2str(functional) // "]/functional_value", stat=stat)
146 end do
147
148 end subroutine mangle_options_tree_forward142 end subroutine mangle_options_tree_forward
149143
150 subroutine mangle_options_tree_adjoint144 subroutine mangle_options_tree_adjoint
@@ -262,8 +256,13 @@
262 path = "/material_phase[" // int2str(state) // "]/scalar_field::"256 path = "/material_phase[" // int2str(state) // "]/scalar_field::"
263 call move_option(trim(path) // trim(fields_to_move(field)), trim(path) // "Adjoint" // trim(fields_to_move(field)), stat=stat)257 call move_option(trim(path) // trim(fields_to_move(field)), trim(path) // "Adjoint" // trim(fields_to_move(field)), stat=stat)
264 assert(stat == SPUD_NO_ERROR)258 assert(stat == SPUD_NO_ERROR)
265 ! Delete any sources specified for the forward model -- we deal with these ourselves259 ! Delete the sources specified for the forward model -- if desired
266 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/scalar_field::Source", stat=stat)260 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/scalar_field::Source/")) then
261 if (have_option(trim(complete_field_path(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/scalar_field::Source/")) &
262 & // "adjoint_storage/exists_in_forward")) then
263 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/scalar_field::Source", stat=stat)
264 end if
265 end if
267 ! And delete any initial conditions -- we will also specify these266 ! And delete any initial conditions -- we will also specify these
268 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition")) then267 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition")) then
269 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition", stat=stat)268 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition", stat=stat)
@@ -294,7 +293,12 @@
294 call move_option(trim(path) // trim(fields_to_move(field)), trim(path) // "Adjoint" // trim(fields_to_move(field)), stat=stat)293 call move_option(trim(path) // trim(fields_to_move(field)), trim(path) // "Adjoint" // trim(fields_to_move(field)), stat=stat)
295 assert(stat == SPUD_NO_ERROR)294 assert(stat == SPUD_NO_ERROR)
296 ! Delete any sources specified for the forward model -- we deal with these ourselves295 ! Delete any sources specified for the forward model -- we deal with these ourselves
297 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/vector_field::Source", stat=stat)296 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/vector_field::Source/")) then
297 if (have_option(trim(complete_field_path(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/vector_field::Source/")) &
298 & // "adjoint_storage/exists_in_forward")) then
299 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/vector_field::Source", stat=stat)
300 end if
301 end if
298 ! And delete any initial conditions -- we will also specify these302 ! And delete any initial conditions -- we will also specify these
299 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition")) then303 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition")) then
300 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition", stat=stat)304 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition", stat=stat)
@@ -325,7 +329,12 @@
325 call move_option(trim(path) // trim(fields_to_move(field)), trim(path) // "Adjoint" // trim(fields_to_move(field)), stat=stat)329 call move_option(trim(path) // trim(fields_to_move(field)), trim(path) // "Adjoint" // trim(fields_to_move(field)), stat=stat)
326 assert(stat == SPUD_NO_ERROR)330 assert(stat == SPUD_NO_ERROR)
327 ! Delete any sources specified for the forward model -- we deal with these ourselves331 ! Delete any sources specified for the forward model -- we deal with these ourselves
328 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/tensor_field::Source", stat=stat)332 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/tensor_field::Source/")) then
333 if (have_option(trim(complete_field_path(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/tensor_field::Source/")) &
334 & // "adjoint_storage/exists_in_forward")) then
335 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/tensor_field::Source", stat=stat)
336 end if
337 end if
329 ! And delete any initial conditions -- we will also specify these338 ! And delete any initial conditions -- we will also specify these
330 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition")) then339 if (have_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition")) then
331 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition", stat=stat)340 call delete_option(trim(path) // "Adjoint" // trim(fields_to_move(field)) // "/prognostic/initial_condition", stat=stat)
332341
=== modified file 'adjoint/Shallow_Water_Adjoint_Callbacks.F90'
--- adjoint/Shallow_Water_Adjoint_Callbacks.F90 2011-05-13 14:06:12 +0000
+++ adjoint/Shallow_Water_Adjoint_Callbacks.F90 2011-07-12 15:56:32 +0000
@@ -982,5 +982,6 @@
982 end select982 end select
983 end if983 end if
984 end subroutine shallow_water_forward_source984 end subroutine shallow_water_forward_source
985
985#endif986#endif
986end module shallow_water_adjoint_callbacks987end module shallow_water_adjoint_callbacks
987988
=== added file 'adjoint/Shallow_Water_Control_Callbacks.F90'
--- adjoint/Shallow_Water_Control_Callbacks.F90 1970-01-01 00:00:00 +0000
+++ adjoint/Shallow_Water_Control_Callbacks.F90 2011-07-12 15:56:32 +0000
@@ -0,0 +1,203 @@
1! Copyright (C) 2006 Imperial College London and others.
2!
3! Please see the AUTHORS file in the main source directory for a full list
4! of copyright holders.
5!
6! Prof. C Pain
7! Applied Modelling and Computation Group
8! Department of Earth Science and Engineering
9! Imperial College London
10!
11! amcgsoftware@imperial.ac.uk
12!
13! This library is free software; you can redistribute it and/or
14! modify it under the terms of the GNU Lesser General Public
15! License as published by the Free Software Foundation,
16! version 2.1 of the License.
17!
18! This library is distributed in the hope that it will be useful,
19! but WITHOUT ANY WARRANTY; without even the implied warranty of
20! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21! Lesser General Public License for more details.
22!
23! You should have received a copy of the GNU Lesser General Public
24! License along with this library; if not, write to the Free Software
25! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26! USA
27
28#include "fdebug.h"
29
30module shallow_water_adjoint_controls
31 use fields
32 use global_parameters, only : PYTHON_FUNC_LEN, OPTION_PATH_LEN
33 use spud
34 use state_module
35 use python_state
36 use sparse_matrices_fields
37 use manifold_projections
38
39 implicit none
40
41 private
42
43 public :: shallow_water_adjoint_timestep_callback
44
45 contains
46
47 ! Data is a void pointer used to pass variables into the callback
48 subroutine shallow_water_adjoint_timestep_callback(states, timestep, functional_name, data)
49 use iso_c_binding, only: c_ptr
50 use global_parameters, only: OPTION_PATH_LEN
51 use state_module
52 type(state_type), dimension(:), intent(inout) :: states
53 integer, intent(in) :: timestep
54 character(len=*), intent(in) :: functional_name
55 type(c_ptr), intent(in) :: data
56
57 type(state_type), pointer :: matrices
58 character(len=OPTION_PATH_LEN) :: field_name, control_type, control_deriv_name, field_deriv_name, name, material_phase_name
59 integer :: nb_controls
60 integer :: i, state_id, s_idx
61 type(scalar_field), pointer :: sfield, adj_sfield, adj_sfield2
62 type(vector_field), pointer :: vfield, adj_vfield, positions
63 type(tensor_field), pointer :: tfield, adj_tfield
64 type(block_csr_matrix), pointer :: big_mat, div_mat, u_mass_mat
65 type(csr_matrix), pointer :: h_mass_mat
66
67 type(vector_field) :: local_src_tmp, local_src_tmp2, src_tmp
68 real :: theta, d0, dt
69
70 ! Cast the data to the matrices state
71 call c_f_pointer(data, matrices)
72
73
74 nb_controls = option_count("/adjoint/controls/control")
75 do i = 0, nb_controls-1
76 call get_option("/adjoint/controls/control[" // int2str(i) //"]/name", control_deriv_name)
77 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type/name", control_type)
78 call get_option("/adjoint/controls/control[" // int2str(i) //"]/type::" // trim(control_type) // "/field_name", name)
79 s_idx = scan(trim(name), "::")
80 if (s_idx == 0) then
81 FLAbort("The control " // trim(control_deriv_name) // " uses an invalid field_name. It should be of the form Materialphase::Fieldname")
82 end if
83 material_phase_name = name(1:s_idx - 1)
84 field_name = name(s_idx + 2:len_trim(name))
85 ! Find state associated with the material phase
86 do state_id = 1, size(states)
87 if (trim(states(state_id)%name) == trim(material_phase_name)) then
88 exit
89 end if
90 end do
91 ! Make sure we found the state
92 if (.not. trim(states(state_id)%name) == trim(material_phase_name)) then
93 FLAbort("Could not find state " // trim(material_phase_name) // " as specified in control " // trim(control_deriv_name) // ".")
94 end if
95
96 control_deriv_name = trim(control_deriv_name) // "_TotalDerivative"
97 select case(trim(control_type))
98 !!!!!!!!!!!!! Initial condition !!!!!!!!!!!!
99 case ("initial_condition")
100 if (timestep /= 0) then
101 cycle
102 end if
103 field_deriv_name = trim(functional_name) // "_" // control_deriv_name
104 if (has_scalar_field(states(state_id), field_deriv_name)) then
105 if (trim(field_name) == "LayerThickness") then
106 adj_sfield => extract_scalar_field(states(state_id), "Adjoint" // trim(field_name))
107 sfield => extract_scalar_field(states(state_id), field_deriv_name) ! Output field
108 h_mass_mat => extract_csr_matrix(matrices, "LayerThicknessMassMatrix")
109 call mult(sfield, h_mass_mat, adj_sfield)
110 else
111 FLAbort("Sorry, I do not know how to compute the intial condition control for " // trim(field_name) // ".")
112 end if
113 elseif (has_vector_field(states(state_id), field_deriv_name)) then
114 if (trim(field_name) == "Velocity") then
115 adj_vfield => extract_vector_field(states(state_id), "Adjoint" // trim(field_name))
116 vfield => extract_vector_field(states(state_id), field_deriv_name) ! Output field
117 u_mass_mat => extract_block_csr_matrix(matrices, "CartesianVelocityMassMatrix")
118 call mult(vfield, u_mass_mat, adj_vfield)
119 else
120 FLAbort("Sorry, I do not know how to compute the intial condition control for " // trim(field_name) // ".")
121 end if
122 elseif (has_tensor_field(states(state_id), field_deriv_name)) then
123 tfield => extract_tensor_field(states(state_id), field_deriv_name) ! Output field
124 FLAbort("Sorry, I do not know how to compute the intial condition control for " // trim(field_name) // ".")
125 else
126 FLAbort("The control derivative field " // trim(field_deriv_name) // " specified for " // trim(control_deriv_name) // " is not a field in the state.")
127 end if
128 !!!!!!!!!!!!! Boundary condition !!!!!!!!!!!!
129 case("boundary_condition")
130 FLAbort("Boundary condition control not implemented yet.")
131 !!!!!!!!!!!!! Source !!!!!!!!!!!!
132 case("source_term")
133 if (timestep == 0) then
134 cycle
135 end if
136 field_deriv_name = trim(functional_name) // "_" // control_deriv_name
137 call get_option("/timestepping/timestep", dt)
138 if (has_scalar_field(states(state_id), field_deriv_name)) then
139 if (trim(field_name) == "LayerThicknessSource") then
140 adj_sfield => extract_scalar_field(states(state_id), "AdjointLayerThicknessDelta")
141 sfield => extract_scalar_field(states(state_id), field_deriv_name) ! Output field
142 h_mass_mat => extract_csr_matrix(matrices, "LayerThicknessMassMatrix")
143 call mult_T(sfield, h_mass_mat, adj_sfield)
144 call scale(sfield, abs(dt))
145 else
146 FLAbort("Sorry, I do not know how to compute the source condition control for " // trim(field_name) // ".")
147 end if
148 elseif (has_vector_field(states(state_id), field_deriv_name)) then
149 if (trim(field_name) == "VelocitySource") then
150 ! We want to compute:
151 ! \lambda_{delta \eta} \Delta t^2 d_0 \theta C^T (M+\theta \Delta t L)^{-1} M P_{Cart to local}
152 vfield => extract_vector_field(states(state_id), field_deriv_name) ! Output field
153 adj_sfield => extract_scalar_field(states(state_id), "AdjointLayerThicknessDelta")
154 adj_vfield => extract_vector_field(states(state_id), "AdjointLocalVelocityDelta")
155 ! We need the AdjointVelocity for the option path only
156 adj_sfield2 => extract_scalar_field(states(state_id), "AdjointLayerThickness")
157 call get_option(trim(adj_sfield2%option_path) // "/prognostic/temporal_discretisation/theta", theta)
158 call get_option(trim(adj_sfield2%option_path) // "/prognostic/mean_layer_thickness", d0)
159
160 big_mat => extract_block_csr_matrix(matrices, "InverseBigMatrix")
161 div_mat => extract_block_csr_matrix(matrices, "DivergenceMatrix")
162 h_mass_mat => extract_csr_matrix(matrices, "LayerThicknessMassMatrix")
163 u_mass_mat => extract_block_csr_matrix(matrices, "LocalVelocityMassMatrix")
164 positions => extract_vector_field(matrices, "Coordinate")
165
166 call allocate(local_src_tmp, adj_vfield%dim, adj_vfield%mesh, "TemporaryLocalVelocity")
167 call allocate(local_src_tmp2, adj_vfield%dim, adj_vfield%mesh, "TemporaryLocalVelocity2")
168 call allocate(src_tmp, vfield%dim, vfield%mesh, "TemporaryVelocity")
169 call mult_T(local_src_tmp, div_mat, adj_sfield)
170 call mult_T(local_src_tmp2, big_mat, local_src_tmp)
171 call mult_T(local_src_tmp, u_mass_mat, local_src_tmp2)
172 call project_cartesian_to_local(positions, src_tmp, local_src_tmp, transpose=.true.)
173 call scale(src_tmp, factor = dt*dt * d0 * theta)
174 call zero(vfield)
175 ! TODO: Where does this minus come from?
176 call addto(vfield, src_tmp, scale=-1.0)
177
178 ! Now add the part from \lambda_{\Delta u}
179 ! \lambda_{\Delta u} M M_{big} M P_{cart to local}
180 call mult_T(local_src_tmp, u_mass_mat, adj_vfield)
181 call mult_T(local_src_tmp2, big_mat, local_src_tmp)
182 call mult_T(local_src_tmp, u_mass_mat, local_src_tmp2)
183 call project_cartesian_to_local(positions, src_tmp, local_src_tmp, transpose = .true.)
184 call addto(vfield, src_tmp, scale = abs(dt))
185
186 call deallocate(local_src_tmp)
187 call deallocate(local_src_tmp2)
188 call deallocate(src_tmp)
189 else
190 FLAbort("Sorry, I do not know how to compute the source condition control for " // trim(field_name) // ".")
191 end if
192 elseif (has_tensor_field(states(state_id), field_deriv_name)) then
193 tfield => extract_tensor_field(states(state_id), field_deriv_name) ! Output field
194 FLAbort("Sorry, I do not know how to compute the source condition control for " // trim(field_name) // ".")
195 else
196 FLAbort("The control derivative field " // trim(field_deriv_name) // " specified for " // trim(control_deriv_name) // " is not a field in the state.")
197 end if
198 end select
199 end do
200
201 end subroutine shallow_water_adjoint_timestep_callback
202
203end module shallow_water_adjoint_controls
0204
=== added file 'adjoint/adBuffer.c'
--- adjoint/adBuffer.c 1970-01-01 00:00:00 +0000
+++ adjoint/adBuffer.c 2011-07-12 15:56:32 +0000
@@ -0,0 +1,476 @@
1static char adSid[]="$Id: adBuffer.c $";
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6
7#include "adStack.h"
8
9/************ MEASUREMENT OF PUSH/POP TRAFFIC *************/
10
11static int mmftraffic = 0 ;
12static int mmftrafficM = 0 ;
13
14void addftraffic(int n) {
15 mmftraffic = mmftraffic+n ;
16 while (mmftraffic >= 1000000) {
17 mmftraffic = mmftraffic-1000000 ;
18 ++mmftrafficM ;
19 }
20 while (mmftraffic < 0) {
21 mmftraffic = mmftraffic+1000000 ;
22 --mmftraffic ;
23 }
24}
25
26void printtraffic() {
27 printctraffic_() ;
28 printf(" F Traffic: ") ;
29 printbigbytes(mmftrafficM, 1000000, mmftraffic) ;
30 printf(" bytes\n") ;
31}
32
33/************************** integer*4 ************************/
34static int adi4buf[512] ;
35static int adi4ibuf = 0 ;
36static int adi4lbuf[512] ;
37static int adi4ilbuf = -1 ;
38static int adi4inlbuf = 0 ;
39
40void pushinteger4(int x) {
41 addftraffic(4) ;
42 if (adi4ilbuf != -1) {
43 adi4ilbuf = -1 ;
44 adi4inlbuf = 0 ;
45 }
46 if (adi4ibuf >= 511) {
47 adi4buf[511] = x ;
48 pushNarray((char*)adi4buf, 512*4) ;
49 addftraffic(-512*4) ;
50 adi4ibuf = 0 ;
51 } else {
52 adi4buf[adi4ibuf] = x ;
53 ++adi4ibuf ;
54 }
55}
56
57void lookinteger4(int *x) {
58 if (adi4ilbuf == -1) {
59 adi4ilbuf = adi4ibuf ;
60 resetadlookstack_() ;
61 }
62 if (adi4ilbuf <= 0) {
63 lookNarray((char*)adi4lbuf, 512*4) ;
64 adi4inlbuf = 1 ;
65 adi4ilbuf = 511 ;
66 *x = adi4lbuf[511] ;
67 } else {
68 --adi4ilbuf ;
69 if (adi4inlbuf)
70 *x = adi4lbuf[adi4ilbuf] ;
71 else
72 *x = adi4buf[adi4ilbuf] ;
73 }
74}
75
76void popinteger4(int *x) {
77 if (adi4ilbuf != -1) {
78 adi4ilbuf = -1 ;
79 adi4inlbuf = 0 ;
80 }
81 if (adi4ibuf <= 0) {
82 popNarray((char*)adi4buf, 512*4) ;
83 adi4ibuf = 511 ;
84 *x = adi4buf[511] ;
85 } else {
86 --adi4ibuf ;
87 *x = adi4buf[adi4ibuf] ;
88 }
89}
90
91/*************************** bits *************************/
92static unsigned int adbitbuf = 0 ;
93static int adbitibuf = 1 ;
94static unsigned int adbitlbuf = 0 ;
95static int adbitilbuf = -1 ;
96static int adbitinlbuf = 0 ;
97
98void pushbit(int bit) {
99 if (adbitilbuf != -1) {
100 adbitilbuf = -1 ;
101 adbitinlbuf = 0 ;
102 }
103 adbitbuf<<=1 ;
104 if (bit) adbitbuf++ ;
105 if (adbitibuf>=32) {
106 pushinteger4(adbitbuf) ;
107 adbitbuf = 0 ;
108 adbitibuf = 1 ;
109 } else
110 adbitibuf++ ;
111}
112
113int lookbit() {
114 if (adbitilbuf==-1) {
115 adbitilbuf=adbitibuf ;
116 adbitlbuf = adbitbuf ;
117 }
118 if (adbitilbuf<=1) {
119 lookinteger4(&adbitlbuf) ;
120 adbitilbuf = 32 ;
121 } else
122 adbitilbuf-- ;
123 int bit = adbitlbuf%2 ;
124 adbitlbuf>>=1 ;
125 return bit ;
126}
127
128int popbit() {
129 if (adbitilbuf != -1) {
130 adbitilbuf = -1 ;
131 adbitinlbuf = 0 ;
132 }
133 if (adbitibuf<=1) {
134 popinteger4(&adbitbuf) ;
135 adbitibuf = 32 ;
136 } else
137 adbitibuf-- ;
138 int bit = adbitbuf%2 ;
139 adbitbuf>>=1 ;
140 return bit ;
141}
142
143/************************* controls ***********************/
144
145void pushcontrol1b(int cc) {
146 pushbit(cc) ;
147}
148
149void popcontrol1b(int *cc) {
150 *cc = (popbit()?1:0) ;
151}
152
153void lookcontrol1b(int *cc) {
154 *cc = (lookbit()?1:0) ;
155}
156
157void pushcontrol2b(int cc) {
158 pushbit(cc%2) ;
159 cc >>= 1 ;
160 pushbit(cc) ;
161}
162
163void popcontrol2b(int *cc) {
164 *cc = (popbit()?2:0) ;
165 if (popbit()) (*cc)++ ;
166}
167
168void lookcontrol2b(int *cc) {
169 *cc = (lookbit()?2:0) ;
170 if (lookbit()) (*cc)++ ;
171}
172
173void pushcontrol3b(int cc) {
174 pushbit(cc%2) ;
175 cc >>= 1 ;
176 pushbit(cc%2) ;
177 cc >>= 1 ;
178 pushbit(cc) ;
179}
180
181void popcontrol3b(int *cc) {
182 *cc = (popbit()?2:0) ;
183 if (popbit()) (*cc)++ ;
184 (*cc) <<= 1 ;
185 if (popbit()) (*cc)++ ;
186}
187
188void lookcontrol3b(int *cc) {
189 *cc = (lookbit()?2:0) ;
190 if (lookbit()) (*cc)++ ;
191 (*cc) <<= 1 ;
192 if (lookbit()) (*cc)++ ;
193}
194
195void pushcontrol4b(int cc) {
196 pushbit(cc%2) ;
197 cc >>= 1 ;
198 pushbit(cc%2) ;
199 cc >>= 1 ;
200 pushbit(cc%2) ;
201 cc >>= 1 ;
202 pushbit(cc) ;
203}
204
205void popcontrol4b(int *cc) {
206 *cc = (popbit()?2:0) ;
207 if (popbit()) (*cc)++ ;
208 (*cc) <<= 1 ;
209 if (popbit()) (*cc)++ ;
210 (*cc) <<= 1 ;
211 if (popbit()) (*cc)++ ;
212}
213
214void lookcontrol4b(int *cc) {
215 *cc = (lookbit()?2:0) ;
216 if (lookbit()) (*cc)++ ;
217 (*cc) <<= 1 ;
218 if (lookbit()) (*cc)++ ;
219 (*cc) <<= 1 ;
220 if (lookbit()) (*cc)++ ;
221}
222
223void pushcontrol5b(int cc) {
224 pushbit(cc%2) ;
225 cc >>= 1 ;
226 pushbit(cc%2) ;
227 cc >>= 1 ;
228 pushbit(cc%2) ;
229 cc >>= 1 ;
230 pushbit(cc%2) ;
231 cc >>= 1 ;
232 pushbit(cc) ;
233}
234
235void popcontrol5b(int *cc) {
236 *cc = (popbit()?2:0) ;
237 if (popbit()) (*cc)++ ;
238 (*cc) <<= 1 ;
239 if (popbit()) (*cc)++ ;
240 (*cc) <<= 1 ;
241 if (popbit()) (*cc)++ ;
242 (*cc) <<= 1 ;
243 if (popbit()) (*cc)++ ;
244}
245
246void lookcontrol5b(int *cc) {
247 *cc = (lookbit()?2:0) ;
248 if (lookbit()) (*cc)++ ;
249 (*cc) <<= 1 ;
250 if (lookbit()) (*cc)++ ;
251 (*cc) <<= 1 ;
252 if (lookbit()) (*cc)++ ;
253 (*cc) <<= 1 ;
254 if (lookbit()) (*cc)++ ;
255}
256
257/************************** real*4 ************************/
258static float adr4buf[512] ;
259static int adr4ibuf = 0 ;
260static float adr4lbuf[512] ;
261static int adr4ilbuf = -1 ;
262static int adr4inlbuf = 0 ;
263
264void pushreal4(float x) {
265 addftraffic(4) ;
266 if (adr4ilbuf != -1) {
267 adr4ilbuf = -1 ;
268 adr4inlbuf = 0 ;
269 }
270 if (adr4ibuf >= 511) {
271 adr4buf[511] = x ;
272 pushNarray((char*)adr4buf, 512*4) ;
273 addftraffic(-512*4) ;
274 adr4ibuf = 0 ;
275 } else {
276 adr4buf[adr4ibuf] = x ;
277 ++adr4ibuf ;
278 }
279}
280
281void lookreal4(float *x) {
282 if (adr4ilbuf == -1) {
283 adr4ilbuf = adr4ibuf ;
284 resetadlookstack_() ;
285 }
286 if (adr4ilbuf <= 0) {
287 lookNarray((char*)adr4lbuf, 512*4) ;
288 adr4inlbuf = 1 ;
289 adr4ilbuf = 511 ;
290 *x = adr4lbuf[511] ;
291 } else {
292 --adr4ilbuf ;
293 if (adr4inlbuf)
294 *x = adr4lbuf[adr4ilbuf] ;
295 else
296 *x = adr4buf[adr4ilbuf] ;
297 }
298}
299
300void popreal4(float *x) {
301 if (adr4ilbuf != -1) {
302 adr4ilbuf = -1 ;
303 adr4inlbuf = 0 ;
304 }
305 if (adr4ibuf <= 0) {
306 popNarray((char*)adr4buf, 512*4) ;
307 adr4ibuf = 511 ;
308 *x = adr4buf[511] ;
309 } else {
310 --adr4ibuf ;
311 *x = adr4buf[adr4ibuf] ;
312 }
313}
314
315/************************** real*8 ************************/
316static double adr8buf[512] ;
317static int adr8ibuf = 0 ;
318static double adr8lbuf[512] ;
319static int adr8ilbuf = -1 ;
320static int adr8inlbuf = 0 ;
321
322void pushreal8(double x) {
323 addftraffic(8) ;
324 if (adr8ilbuf != -1) {
325 adr8ilbuf = -1 ;
326 adr8inlbuf = 0 ;
327 }
328 if (adr8ibuf >= 511) {
329 adr8buf[511] = x ;
330 pushNarray((char*)adr8buf, 512*8) ;
331 addftraffic(-4096) ;
332 adr8ibuf = 0 ;
333 } else {
334 adr8buf[adr8ibuf] = x ;
335 ++adr8ibuf ;
336 }
337}
338
339void lookreal8(double *x) {
340 if (adr8ilbuf == -1) {
341 adr8ilbuf = adr8ibuf ;
342 resetadlookstack_() ;
343 }
344 if (adr8ilbuf <= 0) {
345 lookNarray((char*)adr8lbuf, 512*8) ;
346 adr8inlbuf = 1 ;
347 adr8ilbuf = 511 ;
348 *x = adr8lbuf[511] ;
349 } else {
350 --adr8ilbuf ;
351 if (adr8inlbuf)
352 *x = adr8lbuf[adr8ilbuf] ;
353 else
354 *x = adr8buf[adr8ilbuf] ;
355 }
356}
357
358void popreal8(double *x) {
359 if (adr8ilbuf != -1) {
360 adr8ilbuf = -1 ;
361 adr8inlbuf = 0 ;
362 }
363 if (adr8ibuf <= 0) {
364 popNarray((char*)adr8buf, 512*8) ;
365 adr8ibuf = 511 ;
366 *x = adr8buf[511] ;
367 } else {
368 --adr8ibuf ;
369 *x = adr8buf[adr8ibuf] ;
370 }
371}
372
373/********* PRINTING THE SIZE OF STACKS AND BUFFERS ********/
374
375void printbuffertop() {
376 int size = 0 ;
377 size += adi4ibuf*4 ;
378 size += adr4ibuf*4 ;
379 size += adr8ibuf*8 ;
380 printf("Buffer size:%i bytes i.e. %i Kbytes\n",
381 size, (int) (size/1024.0)) ;
382}
383
384void showallstacks() {
385 int i ;
386 printf("BIT STACK : %x == %i\n",adbitbuf,adbitbuf) ;
387 printf("INTEGER*4 BUFFER[%i]:",adi4ibuf) ;
388 for (i=0 ; i<adi4ibuf ; ++i) printf(" %i",adi4buf[i]) ;
389 printf("\n") ;
390 printf("REAL*8 BUFFER[%i]:",adr8ibuf) ;
391 for (i=0 ; i<adr8ibuf ; ++i) printf(" %d",(int) adr8buf[i]) ;
392 printf("\n") ;
393 printf("REAL*4 BUFFER[%i]:",adr4ibuf) ;
394 for (i=0 ; i<adr4ibuf ; ++i) printf(" %f",adr4buf[i]) ;
395 printf("\n") ;
396 showrecentcstack_() ;
397}
398
399/**********************************************************
400 * HOW TO CREATE PUSH* LOOK* POP* SUBROUTINES
401 * YET FOR OTHER DATA TYPES
402 * Duplicate and uncomment the commented code below.
403 * In the duplicated code, replace:
404 * ctct -> C type name (e.g. float double, int...)
405 * TTTT -> BASIC TAPENADE TYPE NAME
406 * (in character, boolean, integer, real, complex, pointer,...)
407 * z7 -> LETTER-SIZE FOR TYPE
408 * (in s, b, i, r, c, p, ...)
409 * 7 -> TYPE SIZE IN BYTES
410 * Don't forget to insert the corresponding lines in
411 * procedure printbuffertop(), otherwise the contribution of
412 * this new type to buffer occupation will not be seen.
413 * (not very important anyway...)
414 **********************************************************/
415
416/************************** TTTT*7 ************************/
417/*
418static ctct adz7buf[512] ;
419static int adz7ibuf = 0 ;
420static ctct adz7lbuf[512] ;
421static int adz7ilbuf = -1 ;
422static int adz7inlbuf = 0 ;
423
424void pushTTTT7(ctct x) {
425 addftraffic(7) ;
426 if (adz7ilbuf != -1) {
427 adz7ilbuf = -1 ;
428 adz7inlbuf = 0 ;
429 }
430 if (adz7ibuf >= 511) {
431 adz7buf[511] = x ;
432 pushNarray((char*)adz7buf, 512*7) ;
433 addftraffic(-512*7) ;
434 adz7ibuf = 0 ;
435 } else {
436 adz7buf[adz7ibuf] = x ;
437 ++adz7ibuf ;
438 }
439}
440
441void lookTTTT7(ctct *x) {
442 if (adz7ilbuf == -1) {
443 adz7ilbuf = adz7ibuf ;
444 resetadlookstack_() ;
445 }
446 if (adz7ilbuf <= 0) {
447 lookNarray((char*)adz7lbuf, 512*7) ;
448 adz7inlbuf = 1 ;
449 adz7ilbuf = 511 ;
450 *x = adz7lbuf[511] ;
451 } else {
452 --adz7ilbuf ;
453 if (adz7inlbuf)
454 *x = adz7lbuf[adz7ilbuf] ;
455 else
456 *x = adz7buf[adz7ilbuf] ;
457 }
458}
459
460void popTTTT7(ctct *x) {
461 if (adz7ilbuf != -1) {
462 adz7ilbuf = -1 ;
463 adz7inlbuf = 0 ;
464 }
465 if (adz7ibuf <= 0) {
466 popNarray((char*)adz7buf, 512*7) ;
467 adz7ibuf = 511 ;
468 *x = adz7buf[511] ;
469 } else {
470 --adz7ibuf ;
471 *x = adz7buf[adz7ibuf] ;
472 }
473}
474*/
475
476/**********************************************************/
0477
=== added file 'adjoint/adBufferFortran.f'
--- adjoint/adBufferFortran.f 1970-01-01 00:00:00 +0000
+++ adjoint/adBufferFortran.f 2011-07-12 15:56:32 +0000
@@ -0,0 +1,1848 @@
1C$Id: adBuffer.f 3922 2011-05-19 08:54:39Z llh $
2
3c PISTES D'AMELIORATIONS:
4c Attention aux IF qui peuvent couter cher.
5c On pourrait aussi bufferiser les bits avec N entiers,
6c (1 bit par entier), passer tout le paquet a C et laisser
7c C faire les jongleries de bitsets.
8c On pourrait aussi optimiser en -O3 les primitives de ADFirstAidKit
9c Regarder l'assembleur (option -S (et -o toto.s))
10c Pourchasser les divisions!
11
12 BLOCK DATA LOOKINGORNOT
13 LOGICAL looking
14 COMMON /lookingfbuf/looking
15 DATA looking/.FALSE./
16 END
17
18c======================== BITS ==========================:
19 BLOCK DATA BITS
20 INTEGER*4 adbitbuf, adbitlbuf
21 INTEGER adbitibuf, adbitilbuf
22 LOGICAL adbitinlbuf
23 COMMON /adbitfbuf/adbitbuf,adbitlbuf,
24 + adbitibuf,adbitilbuf,adbitinlbuf
25 DATA adbitbuf/0/
26 DATA adbitlbuf/0/
27 DATA adbitibuf/0/
28 DATA adbitilbuf/-1/
29 DATA adbitinlbuf/.FALSE./
30 END
31
32c [0,31] are the bit indices we can use in an INTEGER
33
34 SUBROUTINE PUSHBIT(bit)
35 LOGICAL bit
36 INTEGER*4 adbitbuf, adbitlbuf
37 INTEGER adbitibuf, adbitilbuf
38 LOGICAL adbitinlbuf
39 COMMON /adbitfbuf/adbitbuf,adbitlbuf,
40 + adbitibuf,adbitilbuf,adbitinlbuf
41 LOGICAL looking
42 COMMON /lookingfbuf/looking
43c
44 IF (adbitilbuf.ne.-1) THEN
45 adbitilbuf = -1
46 adbitinlbuf = .FALSE.
47 looking = .FALSE.
48 ENDIF
49 IF (bit) THEN
50 adbitbuf = IBSET(adbitbuf, adbitibuf)
51 ELSE
52 adbitbuf = IBCLR(adbitbuf, adbitibuf)
53 ENDIF
54 IF (adbitibuf.ge.31) THEN
55 CALL PUSHINTEGER4(adbitbuf)
56 adbitbuf = 0
57 adbitibuf = 0
58 ELSE
59 adbitibuf = adbitibuf+1
60 ENDIF
61 END
62
63 LOGICAL FUNCTION LOOKBIT()
64 INTEGER*4 adbitbuf, adbitlbuf
65 INTEGER adbitibuf, adbitilbuf
66 LOGICAL adbitinlbuf
67 COMMON /adbitfbuf/adbitbuf,adbitlbuf,
68 + adbitibuf,adbitilbuf,adbitinlbuf
69 LOGICAL looking
70 COMMON /lookingfbuf/looking
71c
72 IF (adbitilbuf.eq.-1) THEN
73 adbitilbuf=adbitibuf
74 adbitlbuf = adbitbuf
75 IF (.not.looking) THEN
76 CALL RESETADLOOKSTACK()
77 looking = .TRUE.
78 ENDIF
79 ENDIF
80 IF (adbitilbuf.le.0) THEN
81 CALL LOOKINTEGER4(adbitlbuf)
82 adbitilbuf = 31
83 ELSE
84 adbitilbuf = adbitilbuf-1
85 ENDIF
86 LOOKBIT = BTEST(adbitlbuf, adbitilbuf)
87 END
88
89 LOGICAL FUNCTION POPBIT()
90 INTEGER*4 adbitbuf, adbitlbuf
91 INTEGER adbitibuf, adbitilbuf
92 LOGICAL adbitinlbuf
93 COMMON /adbitfbuf/adbitbuf,adbitlbuf,
94 + adbitibuf,adbitilbuf,adbitinlbuf
95 LOGICAL looking
96 COMMON /lookingfbuf/looking
97c
98 IF (adbitilbuf.ne.-1) THEN
99 adbitilbuf = -1
100 adbitinlbuf = .FALSE.
101 looking = .FALSE.
102 ENDIF
103 IF (adbitibuf.le.0) THEN
104 CALL POPINTEGER4(adbitbuf)
105 adbitibuf = 31
106 ELSE
107 adbitibuf = adbitibuf-1
108 ENDIF
109 POPBIT = BTEST(adbitbuf, adbitibuf)
110 END
111
112c====================== CONTROL =========================:
113
114 SUBROUTINE PUSHCONTROL1B(cc)
115 INTEGER cc
116 CALL PUSHBIT(cc.ne.0)
117 END
118
119 SUBROUTINE POPCONTROL1B(cc)
120 INTEGER cc
121 LOGICAL POPBIT
122 IF (POPBIT()) THEN
123 cc = 1
124 ELSE
125 cc = 0
126 ENDIF
127 END
128
129 SUBROUTINE LOOKCONTROL1B(cc)
130 INTEGER cc
131 LOGICAL LOOKBIT
132 IF (LOOKBIT()) THEN
133 cc = 1
134 ELSE
135 cc = 0
136 ENDIF
137 END
138
139 SUBROUTINE PUSHCONTROL2B(cc)
140 INTEGER cc
141 CALL PUSHBIT(BTEST(cc,0))
142 CALL PUSHBIT(BTEST(cc,1))
143 END
144
145 SUBROUTINE POPCONTROL2B(cc)
146 INTEGER cc
147 LOGICAL POPBIT
148 IF (POPBIT()) THEN
149 cc = 2
150 ELSE
151 cc = 0
152 ENDIF
153 IF (POPBIT()) cc = IBSET(cc,0)
154 END
155
156 SUBROUTINE LOOKCONTROL2B(cc)
157 INTEGER cc
158 LOGICAL LOOKBIT
159 IF (LOOKBIT()) THEN
160 cc = 2
161 ELSE
162 cc = 0
163 ENDIF
164 IF (LOOKBIT()) cc = IBSET(cc,0)
165 END
166
167 SUBROUTINE PUSHCONTROL3B(cc)
168 INTEGER cc
169 CALL PUSHBIT(BTEST(cc,0))
170 CALL PUSHBIT(BTEST(cc,1))
171 CALL PUSHBIT(BTEST(cc,2))
172 END
173
174 SUBROUTINE POPCONTROL3B(cc)
175 INTEGER cc
176 LOGICAL POPBIT
177 IF (POPBIT()) THEN
178 cc = 4
179 ELSE
180 cc = 0
181 ENDIF
182 IF (POPBIT()) cc = IBSET(cc,1)
183 IF (POPBIT()) cc = IBSET(cc,0)
184 END
185
186 SUBROUTINE LOOKCONTROL3B(cc)
187 INTEGER cc
188 LOGICAL LOOKBIT
189 IF (LOOKBIT()) THEN
190 cc = 4
191 ELSE
192 cc = 0
193 ENDIF
194 IF (LOOKBIT()) cc = IBSET(cc,1)
195 IF (LOOKBIT()) cc = IBSET(cc,0)
196 END
197
198 SUBROUTINE PUSHCONTROL4B(cc)
199 INTEGER cc
200 CALL PUSHBIT(BTEST(cc,0))
201 CALL PUSHBIT(BTEST(cc,1))
202 CALL PUSHBIT(BTEST(cc,2))
203 CALL PUSHBIT(BTEST(cc,3))
204 END
205
206 SUBROUTINE POPCONTROL4B(cc)
207 INTEGER cc
208 LOGICAL POPBIT
209 IF (POPBIT()) THEN
210 cc = 8
211 ELSE
212 cc = 0
213 ENDIF
214 IF (POPBIT()) cc = IBSET(cc,2)
215 IF (POPBIT()) cc = IBSET(cc,1)
216 IF (POPBIT()) cc = IBSET(cc,0)
217 END
218
219 SUBROUTINE LOOKCONTROL4B(cc)
220 INTEGER cc
221 LOGICAL LOOKBIT
222 IF (LOOKBIT()) THEN
223 cc = 8
224 ELSE
225 cc = 0
226 ENDIF
227 IF (LOOKBIT()) cc = IBSET(cc,2)
228 IF (LOOKBIT()) cc = IBSET(cc,1)
229 IF (LOOKBIT()) cc = IBSET(cc,0)
230 END
231
232 SUBROUTINE PUSHCONTROL5B(cc)
233 INTEGER cc
234 CALL PUSHBIT(BTEST(cc,0))
235 CALL PUSHBIT(BTEST(cc,1))
236 CALL PUSHBIT(BTEST(cc,2))
237 CALL PUSHBIT(BTEST(cc,3))
238 CALL PUSHBIT(BTEST(cc,4))
239 END
240
241 SUBROUTINE POPCONTROL5B(cc)
242 INTEGER cc
243 LOGICAL POPBIT
244 IF (POPBIT()) THEN
245 cc = 16
246 ELSE
247 cc = 0
248 ENDIF
249 IF (POPBIT()) cc = IBSET(cc,3)
250 IF (POPBIT()) cc = IBSET(cc,2)
251 IF (POPBIT()) cc = IBSET(cc,1)
252 IF (POPBIT()) cc = IBSET(cc,0)
253 END
254
255 SUBROUTINE LOOKCONTROL5B(cc)
256 INTEGER cc
257 LOGICAL LOOKBIT
258 IF (LOOKBIT()) THEN
259 cc = 16
260 ELSE
261 cc = 0
262 ENDIF
263 IF (LOOKBIT()) cc = IBSET(cc,3)
264 IF (LOOKBIT()) cc = IBSET(cc,2)
265 IF (LOOKBIT()) cc = IBSET(cc,1)
266 IF (LOOKBIT()) cc = IBSET(cc,0)
267 END
268
269c======================= BOOLEANS =========================
270
271 SUBROUTINE PUSHBOOLEAN(x)
272 LOGICAL x
273 CALL PUSHBIT(x)
274 END
275
276 SUBROUTINE LOOKBOOLEAN(x)
277 LOGICAL x, LOOKBIT
278 x = LOOKBIT()
279 END
280
281 SUBROUTINE POPBOOLEAN(x)
282 LOGICAL x, POPBIT
283 x = POPBIT()
284 END
285
286c===================== CHARACTERS =======================:
287 BLOCK DATA CHARACTERS
288 CHARACTER ads1buf(512), ads1lbuf(512)
289 INTEGER ads1ibuf,ads1ilbuf
290 LOGICAL ads1inlbuf
291 COMMON /ads1fbuf/ads1buf,ads1lbuf,
292 + ads1ibuf,ads1ilbuf,ads1inlbuf
293 DATA ads1ibuf/1/
294 DATA ads1ilbuf/-1/
295 DATA ads1inlbuf/.FALSE./
296 END
297
298 SUBROUTINE PUSHCHARACTER(x)
299 CHARACTER x, ads1buf(512), ads1lbuf(512)
300 INTEGER ads1ibuf,ads1ilbuf
301 LOGICAL ads1inlbuf
302 COMMON /ads1fbuf/ads1buf,ads1lbuf,
303 + ads1ibuf,ads1ilbuf,ads1inlbuf
304 LOGICAL looking
305 COMMON /lookingfbuf/looking
306c
307 CALL addftraffic(1)
308 IF (ads1ilbuf.ne.-1) THEN
309 ads1ilbuf = -1
310 ads1inlbuf = .FALSE.
311 looking = .FALSE.
312 ENDIF
313 IF (ads1ibuf.ge.512) THEN
314 ads1buf(512) = x
315 CALL PUSHCHARACTERARRAY(ads1buf, 512)
316 CALL addftraffic(-512)
317 ads1ibuf = 1
318 ELSE
319 ads1buf(ads1ibuf) = x
320 ads1ibuf = ads1ibuf+1
321 ENDIF
322 END
323
324 SUBROUTINE LOOKCHARACTER(x)
325 CHARACTER x, ads1buf(512), ads1lbuf(512)
326 INTEGER ads1ibuf,ads1ilbuf
327 LOGICAL ads1inlbuf
328 COMMON /ads1fbuf/ads1buf,ads1lbuf,
329 + ads1ibuf,ads1ilbuf,ads1inlbuf
330 LOGICAL looking
331 COMMON /lookingfbuf/looking
332c
333 IF (ads1ilbuf.eq.-1) THEN
334 ads1ilbuf=ads1ibuf
335 IF (.not.looking) THEN
336 CALL RESETADLOOKSTACK()
337 looking = .TRUE.
338 ENDIF
339 ENDIF
340 IF (ads1ilbuf.le.1) THEN
341 CALL LOOKCHARACTERARRAY(ads1lbuf, 512)
342 ads1inlbuf = .TRUE.
343 ads1ilbuf = 512
344 x = ads1lbuf(512)
345 ELSE
346 ads1ilbuf = ads1ilbuf-1
347 if (ads1inlbuf) THEN
348 x = ads1lbuf(ads1ilbuf)
349 ELSE
350 x = ads1buf(ads1ilbuf)
351 ENDIF
352 ENDIF
353 END
354
355 SUBROUTINE POPCHARACTER(x)
356 CHARACTER x, ads1buf(512), ads1lbuf(512)
357 INTEGER ads1ibuf,ads1ilbuf
358 LOGICAL ads1inlbuf
359 COMMON /ads1fbuf/ads1buf,ads1lbuf,
360 + ads1ibuf,ads1ilbuf,ads1inlbuf
361 LOGICAL looking
362 COMMON /lookingfbuf/looking
363c
364 IF (ads1ilbuf.ne.-1) THEN
365 ads1ilbuf = -1
366 ads1inlbuf = .FALSE.
367 looking = .FALSE.
368 ENDIF
369 IF (ads1ibuf.le.1) THEN
370 CALL POPCHARACTERARRAY(ads1buf, 512)
371 ads1ibuf = 512
372 x = ads1buf(512)
373 ELSE
374 ads1ibuf = ads1ibuf-1
375 x = ads1buf(ads1ibuf)
376 ENDIF
377 END
378
379c======================= INTEGER*4 =========================:
380 BLOCK DATA INTEGERS4
381 INTEGER*4 adi4buf(512), adi4lbuf(512)
382 INTEGER adi4ibuf,adi4ilbuf
383 LOGICAL adi4inlbuf
384 COMMON /adi4fbuf/adi4buf,adi4lbuf,
385 + adi4ibuf,adi4ilbuf,adi4inlbuf
386 DATA adi4ibuf/1/
387 DATA adi4ilbuf/-1/
388 DATA adi4inlbuf/.FALSE./
389 END
390
391 SUBROUTINE PUSHINTEGER4(x)
392 INTEGER*4 x, adi4buf(512), adi4lbuf(512)
393 INTEGER adi4ibuf,adi4ilbuf
394 LOGICAL adi4inlbuf
395 COMMON /adi4fbuf/adi4buf,adi4lbuf,
396 + adi4ibuf,adi4ilbuf,adi4inlbuf
397 LOGICAL looking
398 COMMON /lookingfbuf/looking
399c
400 CALL addftraffic(4)
401 IF (adi4ilbuf.ne.-1) THEN
402 adi4ilbuf = -1
403 adi4inlbuf = .FALSE.
404 looking = .FALSE.
405 ENDIF
406 IF (adi4ibuf.ge.512) THEN
407 adi4buf(512) = x
408 CALL PUSHINTEGER4ARRAY(adi4buf, 512)
409 CALL addftraffic(-2048)
410 adi4ibuf = 1
411 ELSE
412 adi4buf(adi4ibuf) = x
413 adi4ibuf = adi4ibuf+1
414 ENDIF
415 END
416
417 SUBROUTINE LOOKINTEGER4(x)
418 INTEGER*4 x, adi4buf(512), adi4lbuf(512)
419 INTEGER adi4ibuf,adi4ilbuf
420 LOGICAL adi4inlbuf
421 COMMON /adi4fbuf/adi4buf,adi4lbuf,
422 + adi4ibuf,adi4ilbuf,adi4inlbuf
423 LOGICAL looking
424 COMMON /lookingfbuf/looking
425c
426 IF (adi4ilbuf.eq.-1) THEN
427 adi4ilbuf=adi4ibuf
428 IF (.not.looking) THEN
429 CALL RESETADLOOKSTACK()
430 looking = .TRUE.
431 ENDIF
432 ENDIF
433 IF (adi4ilbuf.le.1) THEN
434 CALL LOOKINTEGER4ARRAY(adi4lbuf, 512)
435 adi4inlbuf = .TRUE.
436 adi4ilbuf = 512
437 x = adi4lbuf(512)
438 ELSE
439 adi4ilbuf = adi4ilbuf-1
440 if (adi4inlbuf) THEN
441 x = adi4lbuf(adi4ilbuf)
442 ELSE
443 x = adi4buf(adi4ilbuf)
444 ENDIF
445 ENDIF
446 END
447
448 SUBROUTINE POPINTEGER4(x)
449 INTEGER*4 x, adi4buf(512), adi4lbuf(512)
450 INTEGER adi4ibuf,adi4ilbuf
451 LOGICAL adi4inlbuf
452 COMMON /adi4fbuf/adi4buf,adi4lbuf,
453 + adi4ibuf,adi4ilbuf,adi4inlbuf
454 LOGICAL looking
455 COMMON /lookingfbuf/looking
456c
457 IF (adi4ilbuf.ne.-1) THEN
458 adi4ilbuf = -1
459 adi4inlbuf = .FALSE.
460 looking = .FALSE.
461 ENDIF
462 IF (adi4ibuf.le.1) THEN
463 CALL POPINTEGER4ARRAY(adi4buf, 512)
464 adi4ibuf = 512
465 x = adi4buf(512)
466 ELSE
467 adi4ibuf = adi4ibuf-1
468 x = adi4buf(adi4ibuf)
469 ENDIF
470 END
471
472c======================= INTEGER*8 =========================
473 BLOCK DATA INTEGERS8
474 INTEGER*8 adi8buf(512), adi8lbuf(512)
475 INTEGER adi8ibuf,adi8ilbuf
476 LOGICAL adi8inlbuf
477 COMMON /adi8fbuf/adi8buf,adi8lbuf,
478 + adi8ibuf,adi8ilbuf,adi8inlbuf
479 DATA adi8ibuf/1/
480 DATA adi8ilbuf/-1/
481 DATA adi8inlbuf/.FALSE./
482 END
483
484 SUBROUTINE PUSHINTEGER8(x)
485 INTEGER*8 x, adi8buf(512), adi8lbuf(512)
486 INTEGER adi8ibuf,adi8ilbuf
487 LOGICAL adi8inlbuf
488 COMMON /adi8fbuf/adi8buf,adi8lbuf,
489 + adi8ibuf,adi8ilbuf,adi8inlbuf
490 LOGICAL looking
491 COMMON /lookingfbuf/looking
492c
493 CALL addftraffic(8)
494 IF (adi8ilbuf.ne.-1) THEN
495 adi8ilbuf = -1
496 adi8inlbuf = .FALSE.
497 looking = .FALSE.
498 ENDIF
499 IF (adi8ibuf.ge.512) THEN
500 adi8buf(512) = x
501 CALL PUSHINTEGER8ARRAY(adi8buf, 512)
502 CALL addftraffic(-4096)
503 adi8ibuf = 1
504 ELSE
505 adi8buf(adi8ibuf) = x
506 adi8ibuf = adi8ibuf+1
507 ENDIF
508 END
509
510 SUBROUTINE LOOKINTEGER8(x)
511 INTEGER*8 x, adi8buf(512), adi8lbuf(512)
512 INTEGER adi8ibuf,adi8ilbuf
513 LOGICAL adi8inlbuf
514 COMMON /adi8fbuf/adi8buf,adi8lbuf,
515 + adi8ibuf,adi8ilbuf,adi8inlbuf
516 LOGICAL looking
517 COMMON /lookingfbuf/looking
518c
519 IF (adi8ilbuf.eq.-1) THEN
520 adi8ilbuf=adi8ibuf
521 IF (.not.looking) THEN
522 CALL RESETADLOOKSTACK()
523 looking = .TRUE.
524 ENDIF
525 ENDIF
526 IF (adi8ilbuf.le.1) THEN
527 CALL LOOKINTEGER8ARRAY(adi8lbuf, 512)
528 adi8inlbuf = .TRUE.
529 adi8ilbuf = 512
530 x = adi8lbuf(512)
531 ELSE
532 adi8ilbuf = adi8ilbuf-1
533 if (adi8inlbuf) THEN
534 x = adi8lbuf(adi8ilbuf)
535 ELSE
536 x = adi8buf(adi8ilbuf)
537 ENDIF
538 ENDIF
539 END
540
541 SUBROUTINE POPINTEGER8(x)
542 INTEGER*8 x, adi8buf(512), adi8lbuf(512)
543 INTEGER adi8ibuf,adi8ilbuf
544 LOGICAL adi8inlbuf
545 COMMON /adi8fbuf/adi8buf,adi8lbuf,
546 + adi8ibuf,adi8ilbuf,adi8inlbuf
547 LOGICAL looking
548 COMMON /lookingfbuf/looking
549c
550 IF (adi8ilbuf.ne.-1) THEN
551 adi8ilbuf = -1
552 adi8inlbuf = .FALSE.
553 looking = .FALSE.
554 ENDIF
555 IF (adi8ibuf.le.1) THEN
556 CALL POPINTEGER8ARRAY(adi8buf, 512)
557 adi8ibuf = 512
558 x = adi8buf(512)
559 ELSE
560 adi8ibuf = adi8ibuf-1
561 x = adi8buf(adi8ibuf)
562 ENDIF
563 END
564
565c======================= REAL*4 =========================
566 BLOCK DATA REALS4
567 REAL*4 adr4buf(512), adr4lbuf(512)
568 INTEGER adr4ibuf,adr4ilbuf
569 LOGICAL adr4inlbuf
570 COMMON /adr4fbuf/adr4buf,adr4lbuf,
571 + adr4ibuf,adr4ilbuf,adr4inlbuf
572 DATA adr4ibuf/1/
573 DATA adr4ilbuf/-1/
574 DATA adr4inlbuf/.FALSE./
575 END
576
577 SUBROUTINE PUSHREAL4(x)
578 REAL*4 x, adr4buf(512), adr4lbuf(512)
579 INTEGER adr4ibuf,adr4ilbuf
580 LOGICAL adr4inlbuf
581 COMMON /adr4fbuf/adr4buf,adr4lbuf,
582 + adr4ibuf,adr4ilbuf,adr4inlbuf
583 LOGICAL looking
584 COMMON /lookingfbuf/looking
585c
586 CALL addftraffic(4)
587 IF (adr4ilbuf.ne.-1) THEN
588 adr4ilbuf = -1
589 adr4inlbuf = .FALSE.
590 looking = .FALSE.
591 ENDIF
592 IF (adr4ibuf.ge.512) THEN
593 adr4buf(512) = x
594 CALL PUSHREAL4ARRAY(adr4buf, 512)
595 CALL addftraffic(-2048)
596 adr4ibuf = 1
597 ELSE
598 adr4buf(adr4ibuf) = x
599 adr4ibuf = adr4ibuf+1
600 ENDIF
601 END
602
603 SUBROUTINE LOOKREAL4(x)
604 REAL*4 x, adr4buf(512), adr4lbuf(512)
605 INTEGER adr4ibuf,adr4ilbuf
606 LOGICAL adr4inlbuf
607 COMMON /adr4fbuf/adr4buf,adr4lbuf,
608 + adr4ibuf,adr4ilbuf,adr4inlbuf
609 LOGICAL looking
610 COMMON /lookingfbuf/looking
611c
612 IF (adr4ilbuf.eq.-1) THEN
613 adr4ilbuf=adr4ibuf
614 IF (.not.looking) THEN
615 CALL RESETADLOOKSTACK()
616 looking = .TRUE.
617 ENDIF
618 ENDIF
619 IF (adr4ilbuf.le.1) THEN
620 CALL LOOKREAL4ARRAY(adr4lbuf, 512)
621 adr4inlbuf = .TRUE.
622 adr4ilbuf = 512
623 x = adr4lbuf(512)
624 ELSE
625 adr4ilbuf = adr4ilbuf-1
626 if (adr4inlbuf) THEN
627 x = adr4lbuf(adr4ilbuf)
628 ELSE
629 x = adr4buf(adr4ilbuf)
630 ENDIF
631 ENDIF
632 END
633
634 SUBROUTINE POPREAL4(x)
635 REAL*4 x, adr4buf(512), adr4lbuf(512)
636 INTEGER adr4ibuf,adr4ilbuf
637 LOGICAL adr4inlbuf
638 COMMON /adr4fbuf/adr4buf,adr4lbuf,
639 + adr4ibuf,adr4ilbuf,adr4inlbuf
640 LOGICAL looking
641 COMMON /lookingfbuf/looking
642c
643 IF (adr4ilbuf.ne.-1) THEN
644 adr4ilbuf = -1
645 adr4inlbuf = .FALSE.
646 looking = .FALSE.
647 ENDIF
648 IF (adr4ibuf.le.1) THEN
649 CALL POPREAL4ARRAY(adr4buf, 512)
650 adr4ibuf = 512
651 x = adr4buf(512)
652 ELSE
653 adr4ibuf = adr4ibuf-1
654 x = adr4buf(adr4ibuf)
655 ENDIF
656 END
657
658c======================= REAL*8 =========================
659 BLOCK DATA REALS8
660 REAL*8 adr8buf(512), adr8lbuf(512)
661 INTEGER adr8ibuf,adr8ilbuf
662 LOGICAL adr8inlbuf
663 COMMON /adr8fbuf/adr8buf,adr8lbuf,
664 + adr8ibuf,adr8ilbuf,adr8inlbuf
665 DATA adr8ibuf/1/
666 DATA adr8ilbuf/-1/
667 DATA adr8inlbuf/.FALSE./
668 END
669
670 SUBROUTINE PUSHREAL8(x)
671 REAL*8 x, adr8buf(512), adr8lbuf(512)
672 INTEGER adr8ibuf,adr8ilbuf
673 LOGICAL adr8inlbuf
674 COMMON /adr8fbuf/adr8buf,adr8lbuf,
675 + adr8ibuf,adr8ilbuf,adr8inlbuf
676 LOGICAL looking
677 COMMON /lookingfbuf/looking
678c
679 CALL addftraffic(8)
680 IF (adr8ilbuf.ne.-1) THEN
681 adr8ilbuf = -1
682 adr8inlbuf = .FALSE.
683 looking = .FALSE.
684 ENDIF
685 IF (adr8ibuf.ge.512) THEN
686 adr8buf(512) = x
687 CALL PUSHREAL8ARRAY(adr8buf, 512)
688 CALL addftraffic(-4096)
689 adr8ibuf = 1
690 ELSE
691 adr8buf(adr8ibuf) = x
692 adr8ibuf = adr8ibuf+1
693 ENDIF
694 END
695
696 SUBROUTINE LOOKREAL8(x)
697 REAL*8 x, adr8buf(512), adr8lbuf(512)
698 INTEGER adr8ibuf,adr8ilbuf
699 LOGICAL adr8inlbuf
700 COMMON /adr8fbuf/adr8buf,adr8lbuf,
701 + adr8ibuf,adr8ilbuf,adr8inlbuf
702 LOGICAL looking
703 COMMON /lookingfbuf/looking
704c
705 IF (adr8ilbuf.eq.-1) THEN
706 adr8ilbuf=adr8ibuf
707 IF (.not.looking) THEN
708 CALL RESETADLOOKSTACK()
709 looking = .TRUE.
710 ENDIF
711 ENDIF
712 IF (adr8ilbuf.le.1) THEN
713 CALL LOOKREAL8ARRAY(adr8lbuf, 512)
714 adr8inlbuf = .TRUE.
715 adr8ilbuf = 512
716 x = adr8lbuf(512)
717 ELSE
718 adr8ilbuf = adr8ilbuf-1
719 if (adr8inlbuf) THEN
720 x = adr8lbuf(adr8ilbuf)
721 ELSE
722 x = adr8buf(adr8ilbuf)
723 ENDIF
724 ENDIF
725 END
726
727 SUBROUTINE POPREAL8(x)
728 REAL*8 x, adr8buf(512), adr8lbuf(512)
729 INTEGER adr8ibuf,adr8ilbuf
730 LOGICAL adr8inlbuf
731 COMMON /adr8fbuf/adr8buf,adr8lbuf,
732 + adr8ibuf,adr8ilbuf,adr8inlbuf
733 LOGICAL looking
734 COMMON /lookingfbuf/looking
735c
736 IF (adr8ilbuf.ne.-1) THEN
737 adr8ilbuf = -1
738 adr8inlbuf = .FALSE.
739 looking = .FALSE.
740 ENDIF
741 IF (adr8ibuf.le.1) THEN
742 CALL POPREAL8ARRAY(adr8buf, 512)
743 adr8ibuf = 512
744 x = adr8buf(512)
745 ELSE
746 adr8ibuf = adr8ibuf-1
747 x = adr8buf(adr8ibuf)
748 ENDIF
749 END
750
751c======================= REAL*16 =========================
752 BLOCK DATA REALS16
753 DOUBLE PRECISION adr16buf(512), adr16lbuf(512)
754 INTEGER adr16ibuf,adr16ilbuf
755 LOGICAL adr16inlbuf
756 COMMON /adr16fbuf/adr16buf,adr16lbuf,
757 + adr16ibuf,adr16ilbuf,adr16inlbuf
758 DATA adr16ibuf/1/
759 DATA adr16ilbuf/-1/
760 DATA adr16inlbuf/.FALSE./
761 END
762
763 SUBROUTINE PUSHREAL16(x)
764 DOUBLE PRECISION x, adr16buf(512), adr16lbuf(512)
765 INTEGER adr16ibuf,adr16ilbuf
766 LOGICAL adr16inlbuf
767 COMMON /adr16fbuf/adr16buf,adr16lbuf,
768 + adr16ibuf,adr16ilbuf,adr16inlbuf
769 LOGICAL looking
770 COMMON /lookingfbuf/looking
771c
772 CALL addftraffic(16)
773 IF (adr16ilbuf.ne.-1) THEN
774 adr16ilbuf = -1
775 adr16inlbuf = .FALSE.
776 looking = .FALSE.
777 ENDIF
778 IF (adr16ibuf.ge.512) THEN
779 adr16buf(512) = x
780 CALL PUSHREAL16ARRAY(adr16buf, 512)
781 CALL addftraffic(-8192)
782 adr16ibuf = 1
783 ELSE
784 adr16buf(adr16ibuf) = x
785 adr16ibuf = adr16ibuf+1
786 ENDIF
787 END
788
789 SUBROUTINE LOOKREAL16(x)
790 DOUBLE PRECISION x, adr16buf(512), adr16lbuf(512)
791 INTEGER adr16ibuf,adr16ilbuf
792 LOGICAL adr16inlbuf
793 COMMON /adr16fbuf/adr16buf,adr16lbuf,
794 + adr16ibuf,adr16ilbuf,adr16inlbuf
795 LOGICAL looking
796 COMMON /lookingfbuf/looking
797c
798 IF (adr16ilbuf.eq.-1) THEN
799 adr16ilbuf=adr16ibuf
800 IF (.not.looking) THEN
801 CALL RESETADLOOKSTACK()
802 looking = .TRUE.
803 ENDIF
804 ENDIF
805 IF (adr16ilbuf.le.1) THEN
806 CALL LOOKREAL16ARRAY(adr16lbuf, 512)
807 adr16inlbuf = .TRUE.
808 adr16ilbuf = 512
809 x = adr16lbuf(512)
810 ELSE
811 adr16ilbuf = adr16ilbuf-1
812 if (adr16inlbuf) THEN
813 x = adr16lbuf(adr16ilbuf)
814 ELSE
815 x = adr16buf(adr16ilbuf)
816 ENDIF
817 ENDIF
818 END
819
820 SUBROUTINE POPREAL16(x)
821 DOUBLE PRECISION x, adr16buf(512), adr16lbuf(512)
822 INTEGER adr16ibuf,adr16ilbuf
823 LOGICAL adr16inlbuf
824 COMMON /adr16fbuf/adr16buf,adr16lbuf,
825 + adr16ibuf,adr16ilbuf,adr16inlbuf
826 LOGICAL looking
827 COMMON /lookingfbuf/looking
828c
829 IF (adr16ilbuf.ne.-1) THEN
830 adr16ilbuf = -1
831 adr16inlbuf = .FALSE.
832 looking = .FALSE.
833 ENDIF
834 IF (adr16ibuf.le.1) THEN
835 CALL POPREAL16ARRAY(adr16buf, 512)
836 adr16ibuf = 512
837 x = adr16buf(512)
838 ELSE
839 adr16ibuf = adr16ibuf-1
840 x = adr16buf(adr16ibuf)
841 ENDIF
842 END
843
844c======================= COMPLEX*8 =========================
845 BLOCK DATA COMPLEXS8
846 COMPLEX*8 adc8buf(512), adc8lbuf(512)
847 INTEGER adc8ibuf,adc8ilbuf
848 LOGICAL adc8inlbuf
849 COMMON /adc8fbuf/adc8buf,adc8lbuf,
850 + adc8ibuf,adc8ilbuf,adc8inlbuf
851 DATA adc8ibuf/1/
852 DATA adc8ilbuf/-1/
853 DATA adc8inlbuf/.FALSE./
854 END
855
856 SUBROUTINE PUSHCOMPLEX8(x)
857 COMPLEX*8 x, adc8buf(512), adc8lbuf(512)
858 INTEGER adc8ibuf,adc8ilbuf
859 LOGICAL adc8inlbuf
860 COMMON /adc8fbuf/adc8buf,adc8lbuf,
861 + adc8ibuf,adc8ilbuf,adc8inlbuf
862 LOGICAL looking
863 COMMON /lookingfbuf/looking
864c
865 CALL addftraffic(8)
866 IF (adc8ilbuf.ne.-1) THEN
867 adc8ilbuf = -1
868 adc8inlbuf = .FALSE.
869 looking = .FALSE.
870 ENDIF
871 IF (adc8ibuf.ge.512) THEN
872 adc8buf(512) = x
873 CALL PUSHCOMPLEX8ARRAY(adc8buf, 512)
874 CALL addftraffic(-4096)
875 adc8ibuf = 1
876 ELSE
877 adc8buf(adc8ibuf) = x
878 adc8ibuf = adc8ibuf+1
879 ENDIF
880 END
881
882 SUBROUTINE LOOKCOMPLEX8(x)
883 COMPLEX*8 x, adc8buf(512), adc8lbuf(512)
884 INTEGER adc8ibuf,adc8ilbuf
885 LOGICAL adc8inlbuf
886 COMMON /adc8fbuf/adc8buf,adc8lbuf,
887 + adc8ibuf,adc8ilbuf,adc8inlbuf
888 LOGICAL looking
889 COMMON /lookingfbuf/looking
890c
891 IF (adc8ilbuf.eq.-1) THEN
892 adc8ilbuf=adc8ibuf
893 IF (.not.looking) THEN
894 CALL RESETADLOOKSTACK()
895 looking = .TRUE.
896 ENDIF
897 ENDIF
898 IF (adc8ilbuf.le.1) THEN
899 CALL LOOKCOMPLEX8ARRAY(adc8lbuf, 512)
900 adc8inlbuf = .TRUE.
901 adc8ilbuf = 512
902 x = adc8lbuf(512)
903 ELSE
904 adc8ilbuf = adc8ilbuf-1
905 if (adc8inlbuf) THEN
906 x = adc8lbuf(adc8ilbuf)
907 ELSE
908 x = adc8buf(adc8ilbuf)
909 ENDIF
910 ENDIF
911 END
912
913 SUBROUTINE POPCOMPLEX8(x)
914 COMPLEX*8 x, adc8buf(512), adc8lbuf(512)
915 INTEGER adc8ibuf,adc8ilbuf
916 LOGICAL adc8inlbuf
917 COMMON /adc8fbuf/adc8buf,adc8lbuf,
918 + adc8ibuf,adc8ilbuf,adc8inlbuf
919 LOGICAL looking
920 COMMON /lookingfbuf/looking
921c
922 IF (adc8ilbuf.ne.-1) THEN
923 adc8ilbuf = -1
924 adc8inlbuf = .FALSE.
925 looking = .FALSE.
926 ENDIF
927 IF (adc8ibuf.le.1) THEN
928 CALL POPCOMPLEX8ARRAY(adc8buf, 512)
929 adc8ibuf = 512
930 x = adc8buf(512)
931 ELSE
932 adc8ibuf = adc8ibuf-1
933 x = adc8buf(adc8ibuf)
934 ENDIF
935 END
936
937c======================= COMPLEX*16 =========================
938 BLOCK DATA COMPLEXS16
939 COMPLEX*16 adc16buf(512), adc16lbuf(512)
940 INTEGER adc16ibuf,adc16ilbuf
941 LOGICAL adc16inlbuf
942 COMMON /adc16fbuf/adc16buf,adc16lbuf,
943 + adc16ibuf,adc16ilbuf,adc16inlbuf
944 DATA adc16ibuf/1/
945 DATA adc16ilbuf/-1/
946 DATA adc16inlbuf/.FALSE./
947 END
948
949 SUBROUTINE PUSHCOMPLEX16(x)
950 COMPLEX*16 x, adc16buf(512), adc16lbuf(512)
951 INTEGER adc16ibuf,adc16ilbuf
952 LOGICAL adc16inlbuf
953 COMMON /adc16fbuf/adc16buf,adc16lbuf,
954 + adc16ibuf,adc16ilbuf,adc16inlbuf
955 LOGICAL looking
956 COMMON /lookingfbuf/looking
957c
958 CALL addftraffic(16)
959 IF (adc16ilbuf.ne.-1) THEN
960 adc16ilbuf = -1
961 adc16inlbuf = .FALSE.
962 looking = .FALSE.
963 ENDIF
964 IF (adc16ibuf.ge.512) THEN
965 adc16buf(512) = x
966 CALL PUSHCOMPLEX16ARRAY(adc16buf, 512)
967 CALL addftraffic(-8192)
968 adc16ibuf = 1
969 ELSE
970 adc16buf(adc16ibuf) = x
971 adc16ibuf = adc16ibuf+1
972 ENDIF
973 END
974
975 SUBROUTINE LOOKCOMPLEX16(x)
976 COMPLEX*16 x, adc16buf(512), adc16lbuf(512)
977 INTEGER adc16ibuf,adc16ilbuf
978 LOGICAL adc16inlbuf
979 COMMON /adc16fbuf/adc16buf,adc16lbuf,
980 + adc16ibuf,adc16ilbuf,adc16inlbuf
981 LOGICAL looking
982 COMMON /lookingfbuf/looking
983c
984 IF (adc16ilbuf.eq.-1) THEN
985 adc16ilbuf=adc16ibuf
986 IF (.not.looking) THEN
987 CALL RESETADLOOKSTACK()
988 looking = .TRUE.
989 ENDIF
990 ENDIF
991 IF (adc16ilbuf.le.1) THEN
992 CALL LOOKCOMPLEX16ARRAY(adc16lbuf, 512)
993 adc16inlbuf = .TRUE.
994 adc16ilbuf = 512
995 x = adc16lbuf(512)
996 ELSE
997 adc16ilbuf = adc16ilbuf-1
998 if (adc16inlbuf) THEN
999 x = adc16lbuf(adc16ilbuf)
1000 ELSE
1001 x = adc16buf(adc16ilbuf)
1002 ENDIF
1003 ENDIF
1004 END
1005
1006 SUBROUTINE POPCOMPLEX16(x)
1007 COMPLEX*16 x, adc16buf(512), adc16lbuf(512)
1008 INTEGER adc16ibuf,adc16ilbuf
1009 LOGICAL adc16inlbuf
1010 COMMON /adc16fbuf/adc16buf,adc16lbuf,
1011 + adc16ibuf,adc16ilbuf,adc16inlbuf
1012 LOGICAL looking
1013 COMMON /lookingfbuf/looking
1014c
1015 IF (adc16ilbuf.ne.-1) THEN
1016 adc16ilbuf = -1
1017 adc16inlbuf = .FALSE.
1018 looking = .FALSE.
1019 ENDIF
1020 IF (adc16ibuf.le.1) THEN
1021 CALL POPCOMPLEX16ARRAY(adc16buf, 512)
1022 adc16ibuf = 512
1023 x = adc16buf(512)
1024 ELSE
1025 adc16ibuf = adc16ibuf-1
1026 x = adc16buf(adc16ibuf)
1027 ENDIF
1028 END
1029
1030C=========== MEASUREMENT OF PUSH/POP TRAFFIC ==========
1031
1032 BLOCK DATA MEMTRAFFIC
1033 INTEGER*8 mmftraffic,mmftrafficM
1034 COMMON /mmcomtraffic/mmftraffic,mmftrafficM
1035 DATA mmftraffic/0/
1036 DATA mmftrafficM/0/
1037 END
1038
1039 subroutine addftraffic(n)
1040 INTEGER n
1041 INTEGER*8 mmftraffic,mmftrafficM
1042 COMMON /mmcomtraffic/mmftraffic,mmftrafficM
1043c
1044 mmftraffic = mmftraffic+n
1045 if (mmftraffic.ge.1000000) then
1046 100 mmftraffic = mmftraffic-1000000
1047 mmftrafficM = mmftrafficM+1
1048 if (mmftraffic.ge.1000000) then
1049 goto 100
1050 else
1051 goto 300
1052 endif
1053 else if (mmftraffic.lt.0) then
1054 200 mmftraffic = mmftraffic+1000000
1055 mmftrafficM = mmftrafficM-1
1056 if (mmftraffic.lt.0) then
1057 goto 200
1058 else
1059 goto 300
1060 endif
1061 endif
1062 300 continue
1063 END
1064
1065 SUBROUTINE PRINTTRAFFIC()
1066 INTEGER*8 mmftraffic,mmftrafficM
1067 COMMON /mmcomtraffic/mmftraffic,mmftrafficM
1068 CALL printctraffic()
1069 CALL printftrafficinc(mmftrafficM, 1000000, mmftraffic)
1070c write (6,1001) ' F Traffic: ',mmftrafficM,' Mb and ',
1071c + (((mmftraffic*1000)/1024)*1000)/1024, ' millionths'
1072c 1001 format(a,i6,a,i6,a)
1073 END
1074
1075C ============ PRINTING THE SIZE OF STACKS AND BUFFERS ==========
1076
1077 SUBROUTINE PRINTBUFFERTOP()
1078 integer*4 SMALLSTACKSIZE
1079 integer*4 size
1080
1081 size = SMALLSTACKSIZE()
1082 print *,'Buffer size:',size,' bytes i.e. ',size/1024.0,' Kbytes'
1083 END
1084
1085 FUNCTION SMALLSTACKSIZE()
1086 CHARACTER ads1buf(512), ads1lbuf(512)
1087 INTEGER ads1ibuf,ads1ilbuf
1088 LOGICAL ads1inlbuf
1089 COMMON /ads1fbuf/ads1buf,ads1lbuf,
1090 + ads1ibuf,ads1ilbuf,ads1inlbuf
1091c LOGICAL adl4buf(512), adl4lbuf(512)
1092c INTEGER adl4ibuf,adl4ilbuf
1093c LOGICAL adl4inlbuf
1094c COMMON /adl4fbuf/adl4buf,adl4lbuf,
1095c + adl4ibuf,adl4ilbuf,adl4inlbuf
1096 INTEGER*4 adi4buf(512), adi4lbuf(512)
1097 INTEGER adi4ibuf,adi4ilbuf
1098 LOGICAL adi4inlbuf
1099 COMMON /adi4fbuf/adi4buf,adi4lbuf,
1100 + adi4ibuf,adi4ilbuf,adi4inlbuf
1101 INTEGER*8 adi8buf(512), adi8lbuf(512)
1102 INTEGER adi8ibuf,adi8ilbuf
1103 LOGICAL adi8inlbuf
1104 COMMON /adi8fbuf/adi8buf,adi8lbuf,
1105 + adi8ibuf,adi8ilbuf,adi8inlbuf
1106c INTEGER*16 adi16buf(512), adi16lbuf(512)
1107c INTEGER adi16ibuf,adi16ilbuf
1108c LOGICAL adi16inlbuf
1109c COMMON /adi16fbuf/adi16buf,adi16lbuf,
1110c + adi16ibuf,adi16ilbuf,adi16inlbuf
1111 REAL*4 adr4buf(512), adr4lbuf(512)
1112 INTEGER adr4ibuf,adr4ilbuf
1113 LOGICAL adr4inlbuf
1114 COMMON /adr4fbuf/adr4buf,adr4lbuf,
1115 + adr4ibuf,adr4ilbuf,adr4inlbuf
1116 REAL*8 adr8buf(512), adr8lbuf(512)
1117 INTEGER adr8ibuf,adr8ilbuf
1118 LOGICAL adr8inlbuf
1119 COMMON /adr8fbuf/adr8buf,adr8lbuf,
1120 + adr8ibuf,adr8ilbuf,adr8inlbuf
1121 DOUBLE PRECISION adr16buf(512), adr16lbuf(512)
1122 INTEGER adr16ibuf,adr16ilbuf
1123 LOGICAL adr16inlbuf
1124 COMMON /adr16fbuf/adr16buf,adr16lbuf,
1125 + adr16ibuf,adr16ilbuf,adr16inlbuf
1126c REAL*32 x, adr32buf(512), adr32lbuf(512)
1127c INTEGER adr32ibuf,adr32ilbuf
1128c LOGICAL adr32inlbuf
1129c COMMON /adr32fbuf/adr32buf,adr32lbuf,
1130c + adr32ibuf,adr32ilbuf,adr32inlbuf
1131c COMPLEX*4 adc4buf(512), adc4lbuf(512)
1132c INTEGER adc4ibuf,adc4ilbuf
1133c LOGICAL adc4inlbuf
1134c COMMON /adc4fbuf/adc4buf,adc4lbuf,
1135c + adc4ibuf,adc4ilbuf,adc4inlbuf
1136 COMPLEX*8 adc8buf(512), adc8lbuf(512)
1137 INTEGER adc8ibuf,adc8ilbuf
1138 LOGICAL adc8inlbuf
1139 COMMON /adc8fbuf/adc8buf,adc8lbuf,
1140 + adc8ibuf,adc8ilbuf,adc8inlbuf
1141 COMPLEX*16 adc16buf(512), adc16lbuf(512)
1142 INTEGER adc16ibuf,adc16ilbuf
1143 LOGICAL adc16inlbuf
1144 COMMON /adc16fbuf/adc16buf,adc16lbuf,
1145 + adc16ibuf,adc16ilbuf,adc16inlbuf
1146c COMPLEX*32 adc32buf(512), adc32lbuf(512)
1147c INTEGER adc32ibuf,adc32ilbuf
1148c LOGICAL adc32inlbuf
1149c COMMON /adc32fbuf/adc32buf,adc32lbuf,
1150c + adc32ibuf,adc32ilbuf,adc32inlbuf
1151 integer*4 smallstacksize
1152c
1153 smallstacksize = 0
1154 smallstacksize = smallstacksize + (ads1ibuf-1)*1
1155c smallstacksize = smallstacksize + (adl4ibuf-1)*4
1156 smallstacksize = smallstacksize + (adi4ibuf-1)*4
1157 smallstacksize = smallstacksize + (adi8ibuf-1)*8
1158c smallstacksize = smallstacksize + (adi16ibuf-1)*16
1159 smallstacksize = smallstacksize + (adr4ibuf-1)*4
1160 smallstacksize = smallstacksize + (adr8ibuf-1)*8
1161 smallstacksize = smallstacksize + (adr16ibuf-1)*16
1162c smallstacksize = smallstacksize + (adr32ibuf-1)*32
1163c smallstacksize = smallstacksize + (adc4ibuf-1)*4
1164 smallstacksize = smallstacksize + (adc8ibuf-1)*8
1165 smallstacksize = smallstacksize + (adc16ibuf-1)*16
1166c smallstacksize = smallstacksize + (adc32ibuf-1)*32
1167c
1168 end
1169
1170c Very complete display of the current size of the
1171c push/look/pop local Fortran stacks and global C stack.
1172 SUBROUTINE PRINTALLBUFFERS()
1173 CHARACTER ads1buf(512), ads1lbuf(512)
1174 INTEGER ads1ibuf,ads1ilbuf
1175 LOGICAL ads1inlbuf
1176 COMMON /ads1fbuf/ads1buf,ads1lbuf,
1177 + ads1ibuf,ads1ilbuf,ads1inlbuf
1178c LOGICAL adl4buf(512), adl4lbuf(512)
1179c INTEGER adl4ibuf,adl4ilbuf
1180c LOGICAL adl4inlbuf
1181c COMMON /adl4fbuf/adl4buf,adl4lbuf,
1182c + adl4ibuf,adl4ilbuf,adl4inlbuf
1183 INTEGER*4 adi4buf(512), adi4lbuf(512)
1184 INTEGER adi4ibuf,adi4ilbuf
1185 LOGICAL adi4inlbuf
1186 COMMON /adi4fbuf/adi4buf,adi4lbuf,
1187 + adi4ibuf,adi4ilbuf,adi4inlbuf
1188 INTEGER*8 adi8buf(512), adi8lbuf(512)
1189 INTEGER adi8ibuf,adi8ilbuf
1190 LOGICAL adi8inlbuf
1191 COMMON /adi8fbuf/adi8buf,adi8lbuf,
1192 + adi8ibuf,adi8ilbuf,adi8inlbuf
1193c INTEGER*16 adi16buf(512), adi16lbuf(512)
1194c INTEGER adi16ibuf,adi16ilbuf
1195c LOGICAL adi16inlbuf
1196c COMMON /adi16fbuf/adi16buf,adi16lbuf,
1197c + adi16ibuf,adi16ilbuf,adi16inlbuf
1198 REAL*4 adr4buf(512), adr4lbuf(512)
1199 INTEGER adr4ibuf,adr4ilbuf
1200 LOGICAL adr4inlbuf
1201 COMMON /adr4fbuf/adr4buf,adr4lbuf,
1202 + adr4ibuf,adr4ilbuf,adr4inlbuf
1203 REAL*8 adr8buf(512), adr8lbuf(512)
1204 INTEGER adr8ibuf,adr8ilbuf
1205 LOGICAL adr8inlbuf
1206 COMMON /adr8fbuf/adr8buf,adr8lbuf,
1207 + adr8ibuf,adr8ilbuf,adr8inlbuf
1208 DOUBLE PRECISION adr16buf(512), adr16lbuf(512)
1209 INTEGER adr16ibuf,adr16ilbuf
1210 LOGICAL adr16inlbuf
1211 COMMON /adr16fbuf/adr16buf,adr16lbuf,
1212 + adr16ibuf,adr16ilbuf,adr16inlbuf
1213c REAL*32 x, adr32buf(512), adr32lbuf(512)
1214c INTEGER adr32ibuf,adr32ilbuf
1215c LOGICAL adr32inlbuf
1216c COMMON /adr32fbuf/adr32buf,adr32lbuf,
1217c + adr32ibuf,adr32ilbuf,adr32inlbuf
1218c COMPLEX*4 adc4buf(512), adc4lbuf(512)
1219c INTEGER adc4ibuf,adc4ilbuf
1220c LOGICAL adc4inlbuf
1221c COMMON /adc4fbuf/adc4buf,adc4lbuf,
1222c + adc4ibuf,adc4ilbuf,adc4inlbuf
1223 COMPLEX*8 adc8buf(512), adc8lbuf(512)
1224 INTEGER adc8ibuf,adc8ilbuf
1225 LOGICAL adc8inlbuf
1226 COMMON /adc8fbuf/adc8buf,adc8lbuf,
1227 + adc8ibuf,adc8ilbuf,adc8inlbuf
1228 COMPLEX*16 adc16buf(512), adc16lbuf(512)
1229 INTEGER adc16ibuf,adc16ilbuf
1230 LOGICAL adc16inlbuf
1231 COMMON /adc16fbuf/adc16buf,adc16lbuf,
1232 + adc16ibuf,adc16ilbuf,adc16inlbuf
1233c COMPLEX*32 adc32buf(512), adc32lbuf(512)
1234c INTEGER adc32ibuf,adc32ilbuf
1235c LOGICAL adc32inlbuf
1236c COMMON /adc32fbuf/adc32buf,adc32lbuf,
1237c + adc32ibuf,adc32ilbuf,adc32inlbuf
1238 integer*4 bsize,lookbsize
1239 integer*4 cblocks, csize, lookcblocks, lookcsize
1240c
1241 call getbigcsizes(cblocks,csize,lookcblocks,lookcsize)
1242 write (6,'(a,i8,a,i5,a,i8,a,i5,a)')
1243 + 'MAIN stack size (in C) :',cblocks,'B +',csize,
1244 + ' (looking:',lookcblocks,'B +',lookcsize,')'
1245 bsize = (ads1ibuf-1)*1
1246 lookbsize = -999
1247 if (ads1inlbuf.or.ads1ilbuf.gt.-1) lookbsize=(ads1ilbuf-1)*1
1248 write (6,'(a,i4,a,i4,a)') 'CHARs :',bsize,
1249 + ' (looking:',lookbsize,')'
1250c bsize = (adl4ibuf-1)*4
1251 bsize = (adi4ibuf-1)*4
1252 lookbsize = -999
1253 if (adi4inlbuf.or.adi4ilbuf.gt.-1) lookbsize=(adi4ilbuf-1)*4
1254 write (6,'(a,i4,a,i4,a)') 'INTs4 :',bsize,
1255 + ' (looking:',lookbsize,')'
1256 bsize = (adi8ibuf-1)*8
1257 lookbsize = -999
1258 if (adi8inlbuf.or.adi8ilbuf.gt.-1) lookbsize=(adi8ilbuf-1)*8
1259 write (6,'(a,i4,a,i4,a)') 'INTs8 :',bsize,
1260 + ' (looking:',lookbsize,')'
1261c bsize = (adi16ibuf-1)*16
1262 bsize = (adr4ibuf-1)*4
1263 lookbsize = -999
1264 if (adr4inlbuf.or.adr4ilbuf.gt.-1) lookbsize=(adr4ilbuf-1)*4
1265 write (6,'(a,i4,a,i4,a)') 'REALs4 :',bsize,
1266 + ' (looking:',lookbsize,')'
1267 bsize = (adr8ibuf-1)*8
1268 lookbsize = -999
1269 if (adr8inlbuf.or.adr8ilbuf.gt.-1) lookbsize=(adr8ilbuf-1)*8
1270 write (6,'(a,i4,a,i4,a)') 'REALs8 :',bsize,
1271 + ' (looking:',lookbsize,')'
1272 bsize = (adr16ibuf-1)*16
1273 lookbsize = -999
1274 if (adr16inlbuf.or.adr16ilbuf.gt.-1) lookbsize=(adr16ilbuf-1)*16
1275 write (6,'(a,i4,a,i4,a)') 'REALs16:',bsize,
1276 + ' (looking:',lookbsize,')'
1277c bsize = (adr32ibuf-1)*32
1278c bsize = (adc4ibuf-1)*4
1279 bsize = (adc8ibuf-1)*8
1280 lookbsize = -999
1281 if (adc8inlbuf.or.adc8ilbuf.gt.-1) lookbsize=(adc8ilbuf-1)*8
1282 write (6,'(a,i4,a,i4,a)') 'CPLXs8 :',bsize,
1283 + ' (looking:',lookbsize,')'
1284 bsize = (adc16ibuf-1)*16
1285 lookbsize = -999
1286 if (adc16inlbuf.or.adc16ilbuf.gt.-1) lookbsize=(adc16ilbuf-1)*16
1287 write (6,'(a,i4,a,i4,a)') 'CPLXs16:',bsize,
1288 + ' (looking:',lookbsize,')'
1289c bsize = (adc32ibuf-1)*32
1290c
1291 end
1292
1293C FOR INTERNAL DEBUGS ONLY:
1294 SUBROUTINE SHOWALLSTACKS()
1295 INTEGER*4 adbitbuf, adbitlbuf
1296 INTEGER adbitibuf, adbitilbuf
1297 LOGICAL adbitinlbuf
1298 COMMON /adbitfbuf/adbitbuf,adbitlbuf,
1299 + adbitibuf,adbitilbuf,adbitinlbuf
1300 CHARACTER ads1buf(512), ads1lbuf(512)
1301 INTEGER ads1ibuf,ads1ilbuf
1302 LOGICAL ads1inlbuf
1303 COMMON /ads1fbuf/ads1buf,ads1lbuf,
1304 + ads1ibuf,ads1ilbuf,ads1inlbuf
1305 INTEGER*4 adi4buf(512), adi4lbuf(512)
1306 INTEGER adi4ibuf,adi4ilbuf
1307 LOGICAL adi4inlbuf
1308 COMMON /adi4fbuf/adi4buf,adi4lbuf,
1309 + adi4ibuf,adi4ilbuf,adi4inlbuf
1310 INTEGER*8 adi8buf(512), adi8lbuf(512)
1311 INTEGER adi8ibuf,adi8ilbuf
1312 LOGICAL adi8inlbuf
1313 COMMON /adi8fbuf/adi8buf,adi8lbuf,
1314 + adi8ibuf,adi8ilbuf,adi8inlbuf
1315 REAL*4 adr4buf(512), adr4lbuf(512)
1316 INTEGER adr4ibuf,adr4ilbuf
1317 LOGICAL adr4inlbuf
1318 COMMON /adr4fbuf/adr4buf,adr4lbuf,
1319 + adr4ibuf,adr4ilbuf,adr4inlbuf
1320 REAL*8 adr8buf(512), adr8lbuf(512)
1321 INTEGER adr8ibuf,adr8ilbuf
1322 LOGICAL adr8inlbuf
1323 COMMON /adr8fbuf/adr8buf,adr8lbuf,
1324 + adr8ibuf,adr8ilbuf,adr8inlbuf
1325 DOUBLE PRECISION adr16buf(512), adr16lbuf(512)
1326 INTEGER adr16ibuf,adr16ilbuf
1327 LOGICAL adr16inlbuf
1328 COMMON /adr16fbuf/adr16buf,adr16lbuf,
1329 + adr16ibuf,adr16ilbuf,adr16inlbuf
1330 COMPLEX*8 adc8buf(512), adc8lbuf(512)
1331 INTEGER adc8ibuf,adc8ilbuf
1332 LOGICAL adc8inlbuf
1333 COMMON /adc8fbuf/adc8buf,adc8lbuf,
1334 + adc8ibuf,adc8ilbuf,adc8inlbuf
1335 COMPLEX*16 adc16buf(512), adc16lbuf(512)
1336 INTEGER adc16ibuf,adc16ilbuf
1337 LOGICAL adc16inlbuf
1338 COMMON /adc16fbuf/adc16buf,adc16lbuf,
1339 + adc16ibuf,adc16ilbuf,adc16inlbuf
1340 INTEGER i
1341c
1342 write (6,1010) 'BIT STACK : ',adbitbuf,'==',adbitbuf,
1343 + ' (',adbitibuf,')'
13441010 format(a,i20,a,z16,a,i2,a)
1345 write (6,1011) 'INTEGER*8 BUFFER[',adi8ibuf-1,']: ',
1346 + (adi8buf(i),i=1,adi8ibuf-1)
1347 write (6,1011) 'INTEGER*4 BUFFER[',adi4ibuf-1,']: ',
1348 + (adi4buf(i),i=1,adi4ibuf-1)
13491011 format(a,i3,a,512(i40))
1350 write (6,1012) 'REAL*16 BUFFER:[',adr16ibuf-1,']: ',
1351 + (adr16buf(i),i=1,adr16ibuf-1)
1352 write (6,1012) 'REAL*8 BUFFER:[',adr8ibuf-1, ']: ',
1353 + (adr8buf(i),i=1,adr8ibuf-1)
1354 write (6,1012) 'REAL*4 BUFFER:[',adr4ibuf-1, ']: ',
1355 + (adr4buf(i),i=1,adr4ibuf-1)
13561012 format(a,i3,a,512(e8.2))
1357 call showrecentcstack()
1358c
1359 END
1360
1361C========================================================
1362C PUSH* POP* SUBROUTINES FOR OTHER DATA TYPES
1363C Uncomment if these types are available on your compiler
1364C and they are needed by the reverse differentiated code
1365C Don't forget to uncomment the corresponding lines in
1366C subroutine PRINTBUFFERTOP, otherwise these types'
1367C contribution to buffer occupation will not be seen.
1368C (not very important anyway...)
1369
1370c======================= INTEGER*16 =========================
1371c BLOCK DATA INTEGERS16
1372c INTEGER*16 adi16buf(512), adi16lbuf(512)
1373c INTEGER adi16ibuf,adi16ilbuf
1374c LOGICAL adi16inlbuf
1375c COMMON /adi16fbuf/adi16buf,adi16lbuf,
1376c + adi16ibuf,adi16ilbuf,adi16inlbuf
1377c DATA adi16ibuf/1/
1378c DATA adi16ilbuf/-1/
1379c DATA adi16inlbuf/.FALSE./
1380c END
1381c c
1382c SUBROUTINE PUSHINTEGER16(x)
1383c INTEGER*16 x, adi16buf(512), adi16lbuf(512)
1384c INTEGER adi16ibuf,adi16ilbuf
1385c LOGICAL adi16inlbuf
1386c COMMON /adi16fbuf/adi16buf,adi16lbuf,
1387c + adi16ibuf,adi16ilbuf,adi16inlbuf
1388c LOGICAL looking
1389c COMMON /lookingfbuf/looking
1390c c
1391c CALL addftraffic(16)
1392c IF (adi16ilbuf.ne.-1) THEN
1393c adi16ilbuf = -1
1394c adi16inlbuf = .FALSE.
1395c looking = .FALSE.
1396c ENDIF
1397c IF (adi16ibuf.ge.512) THEN
1398c adi16buf(512) = x
1399c CALL PUSHINTEGER16ARRAY(adi16buf, 512)
1400c CALL addftraffic(-8192)
1401c adi16ibuf = 1
1402c ELSE
1403c adi16buf(adi16ibuf) = x
1404c adi16ibuf = adi16ibuf+1
1405c ENDIF
1406c END
1407c
1408c SUBROUTINE LOOKINTEGER16(x)
1409c INTEGER*16 x, adi16buf(512), adi16lbuf(512)
1410c INTEGER adi16ibuf,adi16ilbuf
1411c LOGICAL adi16inlbuf
1412c COMMON /adi16fbuf/adi16buf,adi16lbuf,
1413c + adi16ibuf,adi16ilbuf,adi16inlbuf
1414c LOGICAL looking
1415c COMMON /lookingfbuf/looking
1416c c
1417c IF (adi16ilbuf.eq.-1) THEN
1418c adi16ilbuf=adi16ibuf
1419c IF (.not.looking) THEN
1420c CALL RESETADLOOKSTACK()
1421c looking = .TRUE.
1422c ENDIF
1423c ENDIF
1424c IF (adi16ilbuf.le.1) THEN
1425c CALL LOOKINTEGER16ARRAY(adi16lbuf, 512)
1426c adi16inlbuf = .TRUE.
1427c adi16ilbuf = 512
1428c x = adi16lbuf(512)
1429c ELSE
1430c adi16ilbuf = adi16ilbuf-1
1431c if (adi16inlbuf) THEN
1432c x = adi16lbuf(adi16ilbuf)
1433c ELSE
1434c x = adi16buf(adi16ilbuf)
1435c ENDIF
1436c ENDIF
1437c END
1438c
1439c SUBROUTINE POPINTEGER16(x)
1440c INTEGER*16 x, adi16buf(512), adi16lbuf(512)
1441c INTEGER adi16ibuf,adi16ilbuf
1442c LOGICAL adi16inlbuf
1443c COMMON /adi16fbuf/adi16buf,adi16lbuf,
1444c + adi16ibuf,adi16ilbuf,adi16inlbuf
1445c LOGICAL looking
1446c COMMON /lookingfbuf/looking
1447c c
1448c IF (adi16ilbuf.ne.-1) THEN
1449c adi16ilbuf = -1
1450c adi16inlbuf = .FALSE.
1451c looking = .FALSE.
1452c ENDIF
1453c IF (adi16ibuf.le.1) THEN
1454c CALL POPINTEGER16ARRAY(adi16buf, 512)
1455c adi16ibuf = 512
1456c x = adi16buf(512)
1457c ELSE
1458c adi16ibuf = adi16ibuf-1
1459c x = adi16buf(adi16ibuf)
1460c ENDIF
1461c END
1462
1463c======================= REAL*32 =========================
1464c BLOCK DATA REALS32
1465c REAL*32 adr32buf(512), adr32lbuf(512)
1466c INTEGER adr32ibuf,adr32ilbuf
1467c LOGICAL adr32inlbuf
1468c COMMON /adr32fbuf/adr32buf,adr32lbuf,
1469c + adr32ibuf,adr32ilbuf,adr32inlbuf
1470c DATA adr32ibuf/1/
1471c DATA adr32ilbuf/-1/
1472c DATA adr32inlbuf/.FALSE./
1473c END
1474c c
1475c SUBROUTINE PUSHREAL32(x)
1476c REAL*32 x, adr32buf(512), adr32lbuf(512)
1477c INTEGER adr32ibuf,adr32ilbuf
1478c LOGICAL adr32inlbuf
1479c COMMON /adr32fbuf/adr32buf,adr32lbuf,
1480c + adr32ibuf,adr32ilbuf,adr32inlbuf
1481c LOGICAL looking
1482c COMMON /lookingfbuf/looking
1483c c
1484c CALL addftraffic(32)
1485c IF (adr32ilbuf.ne.-1) THEN
1486c adr32ilbuf = -1
1487c adr32inlbuf = .FALSE.
1488c looking = .FALSE.
1489c ENDIF
1490c IF (adr32ibuf.ge.512) THEN
1491c adr32buf(512) = x
1492c CALL PUSHREAL32ARRAY(adr32buf, 512)
1493c CALL addftraffic(-16384)
1494c adr32ibuf = 1
1495c ELSE
1496c adr32buf(adr32ibuf) = x
1497c adr32ibuf = adr32ibuf+1
1498c ENDIF
1499c END
1500c
1501c SUBROUTINE LOOKREAL32(x)
1502c REAL*32 x, adr32buf(512), adr32lbuf(512)
1503c INTEGER adr32ibuf,adr32ilbuf
1504c LOGICAL adr32inlbuf
1505c COMMON /adr32fbuf/adr32buf,adr32lbuf,
1506c + adr32ibuf,adr32ilbuf,adr32inlbuf
1507c LOGICAL looking
1508c COMMON /lookingfbuf/looking
1509c c
1510c IF (adr32ilbuf.eq.-1) THEN
1511c adr32ilbuf=adr32ibuf
1512c IF (.not.looking) THEN
1513c CALL RESETADLOOKSTACK()
1514c looking = .TRUE.
1515c ENDIF
1516c ENDIF
1517c IF (adr32ilbuf.le.1) THEN
1518c CALL LOOKREAL32ARRAY(adr32lbuf, 512)
1519c adr32inlbuf = .TRUE.
1520c adr32ilbuf = 512
1521c x = adr32lbuf(512)
1522c ELSE
1523c adr32ilbuf = adr32ilbuf-1
1524c if (adr32inlbuf) THEN
1525c x = adr32lbuf(adr32ilbuf)
1526c ELSE
1527c x = adr32buf(adr32ilbuf)
1528c ENDIF
1529c ENDIF
1530c END
1531c
1532c SUBROUTINE POPREAL32(x)
1533c REAL*32 x, adr32buf(512), adr32lbuf(512)
1534c INTEGER adr32ibuf,adr32ilbuf
1535c LOGICAL adr32inlbuf
1536c COMMON /adr32fbuf/adr32buf,adr32lbuf,
1537c + adr32ibuf,adr32ilbuf,adr32inlbuf
1538c LOGICAL looking
1539c COMMON /lookingfbuf/looking
1540c c
1541c IF (adr32ilbuf.ne.-1) THEN
1542c adr32ilbuf = -1
1543c adr32inlbuf = .FALSE.
1544c looking = .FALSE.
1545c ENDIF
1546c IF (adr32ibuf.le.1) THEN
1547c CALL POPREAL32ARRAY(adr32buf, 512)
1548c adr32ibuf = 512
1549c x = adr32buf(512)
1550c ELSE
1551c adr32ibuf = adr32ibuf-1
1552c x = adr32buf(adr32ibuf)
1553c ENDIF
1554c END
1555
1556c======================= COMPLEX*4 =========================
1557c BLOCK DATA COMPLEXS4
1558c COMPLEX*4 adc4buf(512), adc4lbuf(512)
1559c INTEGER adc4ibuf,adc4ilbuf
1560c LOGICAL adc4inlbuf
1561c COMMON /adc4fbuf/adc4buf,adc4lbuf,
1562c + adc4ibuf,adc4ilbuf,adc4inlbuf
1563c DATA adc4ibuf/1/
1564c DATA adc4ilbuf/-1/
1565c DATA adc4inlbuf/.FALSE./
1566c END
1567c c
1568c SUBROUTINE PUSHCOMPLEX4(x)
1569c COMPLEX*4 x, adc4buf(512), adc4lbuf(512)
1570c INTEGER adc4ibuf,adc4ilbuf
1571c LOGICAL adc4inlbuf
1572c COMMON /adc4fbuf/adc4buf,adc4lbuf,
1573c + adc4ibuf,adc4ilbuf,adc4inlbuf
1574c LOGICAL looking
1575c COMMON /lookingfbuf/looking
1576c c
1577c CALL addftraffic(4)
1578c IF (adc4ilbuf.ne.-1) THEN
1579c adc4ilbuf = -1
1580c adc4inlbuf = .FALSE.
1581c looking = .FALSE.
1582c ENDIF
1583c IF (adc4ibuf.ge.512) THEN
1584c adc4buf(512) = x
1585c CALL PUSHCOMPLEX4ARRAY(adc4buf, 512)
1586c CALL addftraffic(-2048)
1587c adc4ibuf = 1
1588c ELSE
1589c adc4buf(adc4ibuf) = x
1590c adc4ibuf = adc4ibuf+1
1591c ENDIF
1592c END
1593c
1594c SUBROUTINE LOOKCOMPLEX4(x)
1595c COMPLEX*4 x, adc4buf(512), adc4lbuf(512)
1596c INTEGER adc4ibuf,adc4ilbuf
1597c LOGICAL adc4inlbuf
1598c COMMON /adc4fbuf/adc4buf,adc4lbuf,
1599c + adc4ibuf,adc4ilbuf,adc4inlbuf
1600c LOGICAL looking
1601c COMMON /lookingfbuf/looking
1602c c
1603c IF (adc4ilbuf.eq.-1) THEN
1604c adc4ilbuf=adc4ibuf
1605c IF (.not.looking) THEN
1606c CALL RESETADLOOKSTACK()
1607c looking = .TRUE.
1608c ENDIF
1609c ENDIF
1610c IF (adc4ilbuf.le.1) THEN
1611c CALL LOOKCOMPLEX4ARRAY(adc4lbuf, 512)
1612c adc4inlbuf = .TRUE.
1613c adc4ilbuf = 512
1614c x = adc4lbuf(512)
1615c ELSE
1616c adc4ilbuf = adc4ilbuf-1
1617c if (adc4inlbuf) THEN
1618c x = adc4lbuf(adc4ilbuf)
1619c ELSE
1620c x = adc4buf(adc4ilbuf)
1621c ENDIF
1622c ENDIF
1623c END
1624c
1625c SUBROUTINE POPCOMPLEX4(x)
1626c COMPLEX*4 x, adc4buf(512), adc4lbuf(512)
1627c INTEGER adc4ibuf,adc4ilbuf
1628c LOGICAL adc4inlbuf
1629c COMMON /adc4fbuf/adc4buf,adc4lbuf,
1630c + adc4ibuf,adc4ilbuf,adc4inlbuf
1631c LOGICAL looking
1632c COMMON /lookingfbuf/looking
1633c c
1634c IF (adc4ilbuf.ne.-1) THEN
1635c adc4ilbuf = -1
1636c adc4inlbuf = .FALSE.
1637c looking = .FALSE.
1638c ENDIF
1639c IF (adc4ibuf.le.1) THEN
1640c CALL POPCOMPLEX4ARRAY(adc4buf, 512)
1641c adc4ibuf = 512
1642c x = adc4buf(512)
1643c ELSE
1644c adc4ibuf = adc4ibuf-1
1645c x = adc4buf(adc4ibuf)
1646c ENDIF
1647c END
1648
1649c======================= COMPLEX*32 =========================
1650c BLOCK DATA COMPLEXS32
1651c COMPLEX*32 adc32buf(512), adc32lbuf(512)
1652c INTEGER adc32ibuf,adc32ilbuf
1653c LOGICAL adc32inlbuf
1654c COMMON /adc32fbuf/adc32buf,adc32lbuf,
1655c + adc32ibuf,adc32ilbuf,adc32inlbuf
1656c DATA adc32ibuf/1/
1657c DATA adc32ilbuf/-1/
1658c DATA adc32inlbuf/.FALSE./
1659c END
1660c c
1661c SUBROUTINE PUSHCOMPLEX32(x)
1662c COMPLEX*32 x, adc32buf(512), adc32lbuf(512)
1663c INTEGER adc32ibuf,adc32ilbuf
1664c LOGICAL adc32inlbuf
1665c COMMON /adc32fbuf/adc32buf,adc32lbuf,
1666c + adc32ibuf,adc32ilbuf,adc32inlbuf
1667c LOGICAL looking
1668c COMMON /lookingfbuf/looking
1669c c
1670c CALL addftraffic(32)
1671c IF (adc32ilbuf.ne.-1) THEN
1672c adc32ilbuf = -1
1673c adc32inlbuf = .FALSE.
1674c looking = .FALSE.
1675c ENDIF
1676c IF (adc32ibuf.ge.512) THEN
1677c adc32buf(512) = x
1678c CALL PUSHCOMPLEX32ARRAY(adc32buf, 512)
1679c CALL addftraffic(-16384)
1680c adc32ibuf = 1
1681c ELSE
1682c adc32buf(adc32ibuf) = x
1683c adc32ibuf = adc32ibuf+1
1684c ENDIF
1685c END
1686c
1687c SUBROUTINE LOOKCOMPLEX32(x)
1688c COMPLEX*32 x, adc32buf(512), adc32lbuf(512)
1689c INTEGER adc32ibuf,adc32ilbuf
1690c LOGICAL adc32inlbuf
1691c COMMON /adc32fbuf/adc32buf,adc32lbuf,
1692c + adc32ibuf,adc32ilbuf,adc32inlbuf
1693c LOGICAL looking
1694c COMMON /lookingfbuf/looking
1695c c
1696c IF (adc32ilbuf.eq.-1) THEN
1697c adc32ilbuf=adc32ibuf
1698c IF (.not.looking) THEN
1699c CALL RESETADLOOKSTACK()
1700c looking = .TRUE.
1701c ENDIF
1702c ENDIF
1703c IF (adc32ilbuf.le.1) THEN
1704c CALL LOOKCOMPLEX32ARRAY(adc32lbuf, 512)
1705c adc32inlbuf = .TRUE.
1706c adc32ilbuf = 512
1707c x = adc32lbuf(512)
1708c ELSE
1709c adc32ilbuf = adc32ilbuf-1
1710c if (adc32inlbuf) THEN
1711c x = adc32lbuf(adc32ilbuf)
1712c ELSE
1713c x = adc32buf(adc32ilbuf)
1714c ENDIF
1715c ENDIF
1716c END
1717c
1718c SUBROUTINE POPCOMPLEX32(x)
1719c COMPLEX*32 x, adc32buf(512), adc32lbuf(512)
1720c INTEGER adc32ibuf,adc32ilbuf
1721c LOGICAL adc32inlbuf
1722c COMMON /adc32fbuf/adc32buf,adc32lbuf,
1723c + adc32ibuf,adc32ilbuf,adc32inlbuf
1724c LOGICAL looking
1725c COMMON /lookingfbuf/looking
1726c c
1727c IF (adc32ilbuf.ne.-1) THEN
1728c adc32ilbuf = -1
1729c adc32inlbuf = .FALSE.
1730c looking = .FALSE.
1731c ENDIF
1732c IF (adc32ibuf.le.1) THEN
1733c CALL POPCOMPLEX32ARRAY(adc32buf, 512)
1734c adc32ibuf = 512
1735c x = adc32buf(512)
1736c ELSE
1737c adc32ibuf = adc32ibuf-1
1738c x = adc32buf(adc32ibuf)
1739c ENDIF
1740c END
1741
1742C========================================================
1743C HOW TO CREATE PUSH* POP* SUBROUTINES
1744C YET FOR OTHER DATA TYPES
1745C ** Duplicate the commented program lines below
1746c ** In the duplicated subroutines, replace:
1747c TTTT by the basic name of the type
1748c z9 by the initial and size of the type
1749c (integer:i real:r complex:c boolean:b character:s)
1750c 9 by the size of the type
1751c ** Uncomment the duplicated subroutines
1752C ** Don't forget to insert the corresponding lines in
1753C subroutine PRINTBUFFERTOP, otherwise these types'
1754C contribution to buffer occupation will not be seen.
1755C (not very important anyway...)
1756
1757c======================= TTTT*9 =========================
1758c BLOCK DATA TTTTS9
1759c TTTT*9 adz9buf(512), adz9lbuf(512)
1760c INTEGER adz9ibuf,adz9ilbuf
1761c LOGICAL adz9inlbuf
1762c COMMON /adz9fbuf/adz9buf,adz9lbuf,
1763c + adz9ibuf,adz9ilbuf,adz9inlbuf
1764c DATA adz9ibuf/1/
1765c DATA adz9ilbuf/-1/
1766c DATA adz9inlbuf/.FALSE./
1767c END
1768c c
1769c SUBROUTINE PUSHTTTT9(x)
1770c TTTT*9 x, adz9buf(512), adz9lbuf(512)
1771c INTEGER adz9ibuf,adz9ilbuf
1772c LOGICAL adz9inlbuf
1773c COMMON /adz9fbuf/adz9buf,adz9lbuf,
1774c + adz9ibuf,adz9ilbuf,adz9inlbuf
1775c LOGICAL looking
1776c COMMON /lookingfbuf/looking
1777c c
1778c CALL addftraffic(9)
1779c IF (adz9ilbuf.ne.-1) THEN
1780c adz9ilbuf = -1
1781c adz9inlbuf = .FALSE.
1782c looking = .FALSE.
1783c ENDIF
1784c IF (adz9ibuf.ge.512) THEN
1785c adz9buf(512) = x
1786c CALL PUSHTTTT9ARRAY(adz9buf, 512)
1787c CALL addftraffic(-9*512)
1788c adz9ibuf = 1
1789c ELSE
1790c adz9buf(adz9ibuf) = x
1791c adz9ibuf = adz9ibuf+1
1792c ENDIF
1793c END
1794c
1795c SUBROUTINE LOOKTTTT9(x)
1796c TTTT*9 x, adz9buf(512), adz9lbuf(512)
1797c INTEGER adz9ibuf,adz9ilbuf
1798c LOGICAL adz9inlbuf
1799c COMMON /adz9fbuf/adz9buf,adz9lbuf,
1800c + adz9ibuf,adz9ilbuf,adz9inlbuf
1801c LOGICAL looking
1802c COMMON /lookingfbuf/looking
1803c c
1804c IF (adz9ilbuf.eq.-1) THEN
1805c adz9ilbuf=adz9ibuf
1806c IF (.not.looking) THEN
1807c CALL RESETADLOOKSTACK()
1808c looking = .TRUE.
1809c ENDIF
1810c ENDIF
1811c IF (adz9ilbuf.le.1) THEN
1812c CALL LOOKTTTT9ARRAY(adz9lbuf, 512)
1813c adz9inlbuf = .TRUE.
1814c adz9ilbuf = 512
1815c x = adz9lbuf(512)
1816c ELSE
1817c adz9ilbuf = adz9ilbuf-1
1818c if (adz9inlbuf) THEN
1819c x = adz9lbuf(adz9ilbuf)
1820c ELSE
1821c x = adz9buf(adz9ilbuf)
1822c ENDIF
1823c ENDIF
1824c END
1825c
1826c SUBROUTINE POPTTTT9(x)
1827c TTTT*9 x, adz9buf(512), adz9lbuf(512)
1828c INTEGER adz9ibuf,adz9ilbuf
1829c LOGICAL adz9inlbuf
1830c COMMON /adz9fbuf/adz9buf,adz9lbuf,
1831c + adz9ibuf,adz9ilbuf,adz9inlbuf
1832c LOGICAL looking
1833c COMMON /lookingfbuf/looking
1834c c
1835c IF (adz9ilbuf.ne.-1) THEN
1836c adz9ilbuf = -1
1837c adz9inlbuf = .FALSE.
1838c looking = .FALSE.
1839c ENDIF
1840c IF (adz9ibuf.le.1) THEN
1841c CALL POPTTTT9ARRAY(adz9buf, 512)
1842c adz9ibuf = 512
1843c x = adz9buf(512)
1844c ELSE
1845c adz9ibuf = adz9ibuf-1
1846c x = adz9buf(adz9ibuf)
1847c ENDIF
1848c END
01849
=== added file 'adjoint/adStack.c'
--- adjoint/adStack.c 1970-01-01 00:00:00 +0000
+++ adjoint/adStack.c 2011-07-12 15:56:32 +0000
@@ -0,0 +1,683 @@
1static char adSid[]="$Id: adStack.c 3919 2011-05-18 15:51:18Z llh $";
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6
7#define ONE_BLOCK_SIZE 16384
8#ifndef STACK_SIZE_TRACING
9#define STACK_SIZE_TRACING 1
10#endif
11/* The main stack is a double-chain of DoubleChainedBlock objects.
12 * Each DoubleChainedBlock holds an array[ONE_BLOCK_SIZE] of char. */
13typedef struct _doubleChainedBlock{
14 struct _doubleChainedBlock *prev ;
15 char *contents ;
16 struct _doubleChainedBlock *next ;
17} DoubleChainedBlock ;
18
19/* Globals that define the current position in the stack: */
20static DoubleChainedBlock *curStack = NULL ;
21static char *curStackTop = NULL ;
22/* Globals that define the current LOOKing position in the stack: */
23static DoubleChainedBlock *lookStack = NULL ;
24static char *lookStackTop = NULL ;
25
26static long int mmctraffic = 0 ;
27static long int mmctrafficM = 0 ;
28#ifdef STACK_SIZE_TRACING
29long int bigStackSize = 0;
30#endif
31
32/* PUSHes "nbChars" consecutive chars from a location starting at address "x".
33 * Resets the LOOKing position if it was active.
34 * Checks that there is enough space left to hold "nbChars" chars.
35 * Otherwise, allocates the necessary space. */
36void pushNarray(char *x, unsigned int nbChars) {
37 unsigned int nbmax = (curStack)?ONE_BLOCK_SIZE-(curStackTop-(curStack->contents)):0 ;
38#ifdef STACK_SIZE_TRACING
39 bigStackSize += nbChars;
40#endif
41
42 mmctraffic += nbChars ;
43 while (mmctraffic >= 1000000) {
44 mmctraffic -= 1000000 ;
45 mmctrafficM++ ;
46 }
47
48 lookStack = NULL ;
49 if (nbChars <= nbmax) {
50 memcpy(curStackTop,x,nbChars) ;
51 curStackTop+=nbChars ;
52 } else {
53 char *inx = x+(nbChars-nbmax) ;
54 if (nbmax>0) memcpy(curStackTop,inx,nbmax) ;
55 while (inx>x) {
56 if ((curStack == NULL) || (curStack->next == NULL)) {
57 /* Create new block: */
58 DoubleChainedBlock *newStack ;
59 char *contents = (char*)malloc(ONE_BLOCK_SIZE*sizeof(char)) ;
60 newStack = (DoubleChainedBlock*)malloc(sizeof(DoubleChainedBlock)) ;
61 if ((contents == NULL) || (newStack == NULL)) {
62 DoubleChainedBlock *stack = curStack ;
63 int nbBlocks = (stack?-1:0) ;
64 while(stack) {
65 stack = stack->prev ;
66 nbBlocks++ ;
67 }
68 printf("Out of memory (allocated %i blocks of %i bytes)\n",
69 nbBlocks, ONE_BLOCK_SIZE) ;
70 exit(0);
71 }
72 if (curStack != NULL) curStack->next = newStack ;
73 newStack->prev = curStack ;
74 newStack->next = NULL ;
75 newStack->contents = contents ;
76 curStack = newStack ;
77 /* new block created! */
78 } else
79 curStack = curStack->next ;
80 inx -= ONE_BLOCK_SIZE ;
81 if(inx>x)
82 memcpy(curStack->contents,inx,ONE_BLOCK_SIZE) ;
83 else {
84 unsigned int nbhead = (inx-x)+ONE_BLOCK_SIZE ;
85 curStackTop = curStack->contents ;
86 memcpy(curStackTop,x,nbhead) ;
87 curStackTop += nbhead ;
88 }
89 }
90 }
91}
92
93/* POPs "nbChars" consecutive chars to a location starting at address "x".
94 * Resets the LOOKing position if it was active.
95 * Checks that there is enough data to fill "nbChars" chars.
96 * Otherwise, pops as many blocks as necessary. */
97void popNarray(char *x, unsigned int nbChars) {
98 unsigned int nbmax = curStackTop-(curStack->contents) ;
99#ifdef STACK_SIZE_TRACING
100 bigStackSize -= nbChars;
101#endif
102 lookStack = NULL ;
103 if (nbChars <= nbmax) {
104 curStackTop-=nbChars ;
105 memcpy(x,curStackTop,nbChars);
106 } else {
107 char *tlx = x+nbChars ;
108 if (nbmax>0) memcpy(x,curStack->contents,nbmax) ;
109 x+=nbmax ;
110 while (x<tlx) {
111 curStack = curStack->prev ;
112 if (curStack==NULL) printf("Popping from an empty stack!!!") ;
113 if (x+ONE_BLOCK_SIZE<tlx) {
114 memcpy(x,curStack->contents,ONE_BLOCK_SIZE) ;
115 x += ONE_BLOCK_SIZE ;
116 } else {
117 unsigned int nbtail = tlx-x ;
118 curStackTop=(curStack->contents)+ONE_BLOCK_SIZE-nbtail ;
119 memcpy(x,curStackTop,nbtail) ;
120 x = tlx ;
121 }
122 }
123 }
124}
125
126/* LOOKs "nbChars" consecutive chars to a location starting at address "x".
127 * Activates the LOOKing position if it was reset.
128 * LOOKing is just like POPping, except that the main pointer
129 * remains in place, so that the value is not POPped.
130 * Further PUSHs or POPs will start from the same place as if
131 * no LOOK had been made. */
132void lookNarray(char *x, unsigned int nbChars) {
133 unsigned int nbmax ;
134 if (lookStack == NULL) {
135 lookStack = curStack ;
136 lookStackTop = curStackTop ;
137 }
138 nbmax = lookStackTop-(lookStack->contents) ;
139 if (nbChars <= nbmax) {
140 lookStackTop-=nbChars ;
141 memcpy(x,lookStackTop,nbChars);
142 } else {
143 char *tlx = x+nbChars ;
144 if (nbmax>0) memcpy(x,lookStack->contents,nbmax) ;
145 x+=nbmax ;
146 while (x<tlx) {
147 lookStack = lookStack->prev ;
148 if (lookStack==NULL) printf("Looking into an empty stack!!!") ;
149 if (x+ONE_BLOCK_SIZE<tlx) {
150 memcpy(x,lookStack->contents,ONE_BLOCK_SIZE) ;
151 x += ONE_BLOCK_SIZE ;
152 } else {
153 unsigned int nbtail = tlx-x ;
154 lookStackTop=(lookStack->contents)+ONE_BLOCK_SIZE-nbtail ;
155 memcpy(x,lookStackTop,nbtail) ;
156 x = tlx ;
157 }
158 }
159 }
160}
161
162void resetadlookstack_() {
163 lookStack=NULL ;
164}
165
166/****** Exported PUSH/POP/LOOK functions for ARRAYS: ******/
167/* --> Called from FORTRAN: */
168
169void pushcharacterarray_(char *x, unsigned int *n) {
170 pushNarray(x,*n) ;
171}
172void popcharacterarray_(char *x, unsigned int *n) {
173 popNarray(x,*n) ;
174}
175void lookcharacterarray_(char *x, unsigned int *n) {
176 lookNarray(x,*n) ;
177}
178
179void pushbooleanarray_(char *x, unsigned int *n) {
180 pushNarray(x,(*n*4)) ;
181}
182void popbooleanarray_(char *x, unsigned int *n) {
183 popNarray(x,(*n*4)) ;
184}
185void lookbooleanarray_(char *x, unsigned int *n) {
186 lookNarray(x,(*n*4)) ;
187}
188
189void pushinteger4array_(char *x, unsigned int *n) {
190 pushNarray(x,(*n*4)) ;
191}
192void popinteger4array_(char *x, unsigned int *n) {
193 popNarray(x,(*n*4)) ;
194}
195void lookinteger4array_(char *x, unsigned int *n) {
196 lookNarray(x,(*n*4)) ;
197}
198
199void pushinteger8array_(char *x, unsigned int *n) {
200 pushNarray(x,(*n*8)) ;
201}
202void popinteger8array_(char *x, unsigned int *n) {
203 popNarray(x,(*n*8)) ;
204}
205void lookinteger8array_(char *x, unsigned int *n) {
206 lookNarray(x,(*n*8)) ;
207}
208
209void pushinteger16array_(char *x, unsigned int *n) {
210 pushNarray(x,(*n*16)) ;
211}
212void popinteger16array_(char *x, unsigned int *n) {
213 popNarray(x,(*n*16)) ;
214}
215void lookinteger16array_(char *x, unsigned int *n) {
216 lookNarray(x,(*n*16)) ;
217}
218
219void pushreal4array_(char *x, unsigned int *n) {
220 pushNarray(x,(*n*4)) ;
221}
222void popreal4array_(char *x, unsigned int *n) {
223 popNarray(x,(*n*4)) ;
224}
225void lookreal4array_(char *x, unsigned int *n) {
226 lookNarray(x,(*n*4)) ;
227}
228
229void pushreal8array_(char *x, unsigned int *n) {
230 pushNarray(x,(*n*8)) ;
231}
232void popreal8array_(char *x, unsigned int *n) {
233 popNarray(x,(*n*8)) ;
234}
235void lookreal8array_(char *x, unsigned int *n) {
236 lookNarray(x,(*n*8)) ;
237}
238
239void pushreal16array_(char *x, unsigned int *n) {
240 pushNarray(x,(*n*16)) ;
241}
242void popreal16array_(char *x, unsigned int *n) {
243 popNarray(x,(*n*16)) ;
244}
245void lookreal16array_(char *x, unsigned int *n) {
246 lookNarray(x,(*n*16)) ;
247}
248
249void pushreal32array_(char *x, unsigned int *n) {
250 pushNarray(x,(*n*32)) ;
251}
252void popreal32array_(char *x, unsigned int *n) {
253 popNarray(x,(*n*32)) ;
254}
255void lookreal32array_(char *x, unsigned int *n) {
256 lookNarray(x,(*n*32)) ;
257}
258
259void pushcomplex4array_(char *x, unsigned int *n) {
260 pushNarray(x,(*n*4)) ;
The diff has been truncated for viewing.