Creates a dictionary of indices and values for each parameter in a parameter array to be evaluated later. WARNING: It is not possible to initialize multidimensional array parameters e.g. dimension(-3:1, 4, 3:5) at this point. This is because in Fortran initialization through ar
(v, g_params, params, dimspec=None)
| 2964 | |
| 2965 | |
| 2966 | def param_eval(v, g_params, params, dimspec=None): |
| 2967 | """ |
| 2968 | Creates a dictionary of indices and values for each parameter in a |
| 2969 | parameter array to be evaluated later. |
| 2970 | |
| 2971 | WARNING: It is not possible to initialize multidimensional array |
| 2972 | parameters e.g. dimension(-3:1, 4, 3:5) at this point. This is because in |
| 2973 | Fortran initialization through array constructor requires the RESHAPE |
| 2974 | intrinsic function. Since the right-hand side of the parameter declaration |
| 2975 | is not executed in f2py, but rather at the compiled c/fortran extension, |
| 2976 | later, it is not possible to execute a reshape of a parameter array. |
| 2977 | One issue remains: if the user wants to access the array parameter from |
| 2978 | python, we should either |
| 2979 | 1) allow them to access the parameter array using python standard indexing |
| 2980 | (which is often incompatible with the original fortran indexing) |
| 2981 | 2) allow the parameter array to be accessed in python as a dictionary with |
| 2982 | fortran indices as keys |
| 2983 | We are choosing 2 for now. |
| 2984 | """ |
| 2985 | if dimspec is None: |
| 2986 | try: |
| 2987 | p = eval(v, g_params, params) |
| 2988 | except Exception as msg: |
| 2989 | p = v |
| 2990 | outmess(f'param_eval: got "{msg}" on {v!r}\n') |
| 2991 | return p |
| 2992 | |
| 2993 | # This is an array parameter. |
| 2994 | # First, we parse the dimension information |
| 2995 | if len(dimspec) < 2 or dimspec[::len(dimspec) - 1] != "()": |
| 2996 | raise ValueError(f'param_eval: dimension {dimspec} can\'t be parsed') |
| 2997 | dimrange = dimspec[1:-1].split(',') |
| 2998 | if len(dimrange) == 1: |
| 2999 | # e.g. dimension(2) or dimension(-1:1) |
| 3000 | dimrange = dimrange[0].split(':') |
| 3001 | # now, dimrange is a list of 1 or 2 elements |
| 3002 | if len(dimrange) == 1: |
| 3003 | bound = param_parse(dimrange[0], params) |
| 3004 | dimrange = range(1, int(bound) + 1) |
| 3005 | else: |
| 3006 | lbound = param_parse(dimrange[0], params) |
| 3007 | ubound = param_parse(dimrange[1], params) |
| 3008 | dimrange = range(int(lbound), int(ubound) + 1) |
| 3009 | else: |
| 3010 | raise ValueError('param_eval: multidimensional array parameters ' |
| 3011 | f'{dimspec} not supported') |
| 3012 | |
| 3013 | # Parse parameter value |
| 3014 | v = (v[2:-2] if v.startswith('(/') else v).split(',') |
| 3015 | v_eval = [] |
| 3016 | for item in v: |
| 3017 | try: |
| 3018 | item = eval(item, g_params, params) |
| 3019 | except Exception as msg: |
| 3020 | outmess(f'param_eval: got "{msg}" on {item!r}\n') |
| 3021 | v_eval.append(item) |
| 3022 | |
| 3023 | p = dict(zip(dimrange, v_eval)) |
no test coverage detected
searching dependent graphs…