Retrieve environment variable (JNI)[转]

本文介绍了一种使用JNI(Java本地接口)来检索环境变量的方法。由于JDK中移除了getenv()方法,本文提供了一个JNI例程来实现这一功能。需要注意的是,此方法仅适用于包含常规7位ASCII字符的环境变量。
Retrieve environment variable (JNI)

For some odd reasons, the getenv() method was removed from the JDK. Rumors is that a mechanism to retrieve an environment will be back in JDK1.5 (see this HowTo ). But for now, you can use -D switch to retrieve named environment variable and pass them to the JVM (see this HowTo ) or use this JNI routine :

JNIEXPORT jstring JNICALL JavaHowTo_getenv
  (JNIEnv *env, jclass c, jstring jname){
    if ( jname == NULL ) { 
       return NULL ; 
    }
    const char *name =
       (*env)->GetStringUTFChars(env, jname, (jboolean *)NULL) ;
    const char *value = getenv(name) ;
    (*env)->ReleaseStringUTFChars(env, jname, name) ;
    return value ? (*env)->NewStringUTF(env, value) : NULL ;
}

NOTE : This is fine if the environment variable contains only regular 7-bit ASCII characters.

See also this HowTo .

# -*- coding: utf-8 -*- # # Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import itertools import math import os import warnings import numpy as np from ansys.aedt.core import Quantity from ansys.aedt.core.generic.constants import AEDT_UNITS from ansys.aedt.core.generic.constants import db10 from ansys.aedt.core.generic.constants import db20 from ansys.aedt.core.generic.file_utils import open_file from ansys.aedt.core.generic.file_utils import write_csv from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.generic.settings import settings try: import pandas as pd except ImportError: pd = None warnings.warn( "The Pandas module is required to run some functionalities of PostProcess.\nInstall with \n\npip install pandas" ) class SolutionData(object): """Contains information from the :func:`GetSolutionDataPerVariation` method.""" def __init__(self, aedtdata): self.units_sweeps = {} self._original_data = aedtdata self.number_of_variations = len(aedtdata) self._enable_pandas_output = True if settings.enable_pandas_output and pd else False self._expressions = None self._intrinsics = None self._nominal_variation = None self._nominal_variation = self._original_data[0] self.active_expression = self.expressions[0] self._sweeps_names = [] self.update_sweeps() self.variations = self._get_variations() self.active_intrinsic = {} for k, v in self.intrinsics.items(): self.active_intrinsic[k] = v[0] if len(self.intrinsics) > 0: self._primary_sweep = list(self.intrinsics.keys())[0] else: self._primary_sweep = self._sweeps_names[0] self.active_variation = self.variations[0] self.init_solutions_data() self._ifft = None @property def enable_pandas_output(self): """Set/Get a flag to use Pandas to export dict and lists. This applies to Solution data output. If ``True`` the property or method will return a pandas object in CPython environment. Default is ``False``. Returns ------- bool """ return True if self._enable_pandas_output and pd else False @enable_pandas_output.setter def enable_pandas_output(self, val): if val != self._enable_pandas_output and pd: self._intrinsics = {} self._enable_pandas_output = val self.init_solutions_data() @pyaedt_function_handler() def set_active_variation(self, var_id=0): """Set the active variations to one of available variations in self.variations. Parameters ---------- var_id : int Index of Variations to assign. Returns ------- bool ``True`` when successful, ``False`` when failed. """ if var_id < len(self.variations): self.active_variation = self.variations[var_id] self.nominal_variation = var_id self._expressions = None self._intrinsics = None return True return False @pyaedt_function_handler() def _get_variations(self): variations_lists = [] for data in self._original_data: variations = {} for v in data.GetDesignVariableNames(): variations[v] = Quantity(data.GetDesignVariableValue(v), data.GetDesignVariableUnits(v)) variations_lists.append(variations) return variations_lists @pyaedt_function_handler(variation_name="variation") def variation_values(self, variation): """Get the list of the specific variation available values. Parameters ---------- variation : str Name of variation to return. Returns ------- list List of variation values. """ if variation in self.intrinsics: return self.intrinsics[variation] else: vars_vals = [] for el in self.variations: if variation in el and el[variation] not in vars_vals: vars_vals.append(el[variation]) return vars_vals @property def intrinsics(self): """Get intrinsics dictionary on active variation.""" if not self._intrinsics: self._intrinsics = {} intrinsics = [i for i in self._sweeps_names if i not in self.nominal_variation.GetDesignVariableNames()] for el in intrinsics: values = list(self.nominal_variation.GetSweepValues(el, False)) try: self.units_sweeps[el] = self.nominal_variation.GetSweepUnits(el) except Exception: self.units_sweeps[el] = None values = list(dict.fromkeys(values)) self._intrinsics[el] = [Quantity(i, self.units_sweeps[el]) for i in values] return self._intrinsics @property def nominal_variation(self): """Nominal variation.""" return self._nominal_variation @nominal_variation.setter def nominal_variation(self, val): if 0 <= val <= self.number_of_variations: self._nominal_variation = self._original_data[val] else: print(str(val) + " not in Variations") @property def primary_sweep(self): """Primary sweep. Parameters ---------- ps : float Perimeter of the source. """ return self._primary_sweep @primary_sweep.setter def primary_sweep(self, ps): if ps in self._sweeps_names: self._primary_sweep = ps @property def expressions(self): """Expressions.""" if not self._expressions: mydata = [i for i in self._nominal_variation.GetDataExpressions()] self._expressions = list(dict.fromkeys(mydata)) return self._expressions @pyaedt_function_handler() def update_sweeps(self): """Update sweeps. Returns ------- dict Updated sweeps. """ names = list(self.nominal_variation.GetSweepNames()) for data in self._original_data: for v in data.GetDesignVariableNames(): if v not in self._sweeps_names: self._sweeps_names.append(v) self._sweeps_names.extend((reversed(names))) @staticmethod @pyaedt_function_handler() def _quantity(unit): """Get the corresponding AEDT units. Parameters ---------- unit : str The unit to be looked among the available AEDT units. Returns ------- str The AEDT units. """ for el in AEDT_UNITS: keys_units = [i.lower() for i in list(AEDT_UNITS[el].keys())] if unit.lower() in keys_units: return el return None @pyaedt_function_handler() def init_solutions_data(self): """Initialize the database and store info in variables.""" self._solutions_real = self._init_solution_data_real() self._solutions_imag = self._init_solution_data_imag() self._solutions_mag = self._init_solution_data_mag() self._solutions_phase = self._init_solution_data_phase() @pyaedt_function_handler() def _init_solution_data_mag(self): _solutions_mag = {} self.units_data = {} for expr in self.expressions: _solutions_mag[expr] = {} self.units_data[expr] = self.nominal_variation.GetDataUnits(expr) if self.enable_pandas_output: _solutions_mag[expr] = np.sqrt( self._solutions_real[expr] * self._solutions_real[expr] + self._solutions_imag[expr] * self._solutions_imag[expr] ) else: for i in self._solutions_real[expr]: _solutions_mag[expr][i] = abs(complex(self._solutions_real[expr][i], self._solutions_imag[expr][i])) if self.enable_pandas_output: return pd.DataFrame.from_dict(_solutions_mag) else: return _solutions_mag @pyaedt_function_handler() def __get_index(self, input_data): return tuple([float(i) for i in input_data]) @pyaedt_function_handler() def _init_solution_data_real(self): """Initialize the real part of the solution data.""" sols_data = {} for expression in self.expressions: solution_data = {} for data, comb in zip(self._original_data, self.variations): solution = list(data.GetRealDataValues(expression, False)) values = [] # for el in list(self.intrinsics.keys()): # values.append(list(dict.fromkeys(data.GetSweepValues(el, False)))) for _, val in self.intrinsics.items(): values.append([float(i) for i in val]) i = 0 c = [float(comb[v]) for v in list(comb.keys())] for t in itertools.product(*values): solution_data[tuple(c + list(t))] = solution[i] i += 1 sols_data[expression] = solution_data if self.enable_pandas_output: # series_list = [pd.Series(value, name=key) for key, value in sols_data.items()] # return pd.DataFrame(series_list).T return pd.DataFrame.from_dict(sols_data) else: return sols_data @pyaedt_function_handler() def _init_solution_data_imag(self): """Initialize the imaginary part of the solution data.""" sols_data = {} for expression in self.expressions: solution_data = {} for data, comb in zip(self._original_data, self.variations): if data.IsDataComplex(expression): solution = list(data.GetImagDataValues(expression, False)) else: real_data_length = len(list(data.GetRealDataValues(expression, False))) solution = [0] * real_data_length values = [] for _, val in self.intrinsics.items(): values.append([float(i) for i in val]) i = 0 c = [float(comb[v]) for v in list(comb.keys())] for t in itertools.product(*values): solution_data[tuple(c + list(t))] = solution[i] i += 1 sols_data[expression] = solution_data if self.enable_pandas_output: # series_list = [pd.Series(value, name=key) for key, value in sols_data.items()] # return pd.DataFrame(series_list).T return pd.DataFrame.from_dict(sols_data) else: return sols_data @pyaedt_function_handler() def _init_solution_data_phase(self): data_phase = {} for expr in self.expressions: data_phase[expr] = {} if self.enable_pandas_output: data_phase[expr] = np.arctan2(self._solutions_imag[expr], self._solutions_real[expr]) else: for i in self._solutions_real[expr]: data_phase[expr][i] = math.atan2(self._solutions_imag[expr][i], self._solutions_real[expr][i]) if self.enable_pandas_output: # series_list = [pd.Series(value, name=key) for key, value in data_phase.items()] # return pd.DataFrame(series_list).T return pd.DataFrame.from_dict(data_phase) else: return data_phase @property def full_matrix_real_imag(self): """Get the full available solution data in Real and Imaginary parts. Returns ------- tuple of dicts (Real Dict, Imag Dict) """ return self._solutions_real, self._solutions_imag @property def full_matrix_mag_phase(self): """Get the full available solution data magnitude and phase in radians. Returns ------- tuple of dicts (Mag Dict, Phase Dict). """ return self._solutions_mag, self._solutions_phase @staticmethod @pyaedt_function_handler() def to_degrees(input_list): """Convert an input list from radians to degrees. Parameters ---------- input_list : list List of inputs in radians. Returns ------- list List of inputs in degrees. """ if isinstance(input_list, (tuple, list)): return [i * 360 / (2 * math.pi) for i in input_list] else: return input_list * 360 / (2 * math.pi) @staticmethod @pyaedt_function_handler() def to_radians(input_list): """Convert an input list from degrees to radians. Parameters ---------- input_list : list List of inputs in degrees. Returns ------- type List of inputs in radians. """ if isinstance(input_list, (tuple, list)): return [i * 2 * math.pi / 360 for i in input_list] else: return input_list * 2 * math.pi / 360 @pyaedt_function_handler() def _variation_tuple(self): temp = [] for it in self._sweeps_names: try: temp.append(self.active_variation[it]) except KeyError: temp.append(self.active_intrinsic[it]) return temp @pyaedt_function_handler() def data_magnitude(self, expression=None, convert_to_SI=False): """Retrieve the data magnitude of an expression. Parameters ---------- expression : str, optional Name of the expression. The default is ``None``, in which case the active expression is used. convert_to_SI : bool, optional Whether to convert the data to the SI unit system. The default is ``False``. Returns ------- list List of data. """ if not expression: expression = self.active_expression elif expression not in self.expressions: return False temp = self._variation_tuple() solution_data = self._solutions_mag[expression] sol = [] position = list(self._sweeps_names).index(self.primary_sweep) sw = self.variation_values(self.primary_sweep) for el in sw: temp[position] = el try: sol.append(solution_data[self.__get_index(temp)]) except KeyError: sol.append(None) if convert_to_SI and self._quantity(self.units_data[expression]): sol = self._convert_list_to_SI( sol, self._quantity(self.units_data[expression]), self.units_data[expression] ) if self.enable_pandas_output: return pd.Series(sol) return sol @staticmethod @pyaedt_function_handler(datalist="data", dataunits="data_units") def _convert_list_to_SI(data, data_units, units): """Convert a data list to the SI unit system. Parameters ---------- data : list List of data to convert. data_units : str Data units. units : str SI units to convert data into. Returns ------- list List of the data converted to the SI unit system. """ sol = data if data_units in AEDT_UNITS and units in AEDT_UNITS[data_units]: sol = [i * AEDT_UNITS[data_units][units] for i in data] return sol @pyaedt_function_handler() def data_db10(self, expression=None, convert_to_SI=False): """Retrieve the data in the database for an expression and convert in db10. Parameters ---------- expression : str, optional Name of the expression. The default is ``None``, in which case the active expression is used. convert_to_SI : bool, optional Whether to convert the data to the SI unit system. The default is ``False``. Returns ------- list List of the data in the database for the expression. """ if not expression: expression = self.active_expression if self.enable_pandas_output: return 10 * np.log10(self.data_magnitude(expression, convert_to_SI)) return [db10(i) for i in self.data_magnitude(expression, convert_to_SI)] @pyaedt_function_handler() def data_db20(self, expression=None, convert_to_SI=False): """Retrieve the data in the database for an expression and convert in db20. Parameters ---------- expression : str, optional Name of the expression. The default is ``None``, in which case the active expression is used. convert_to_SI : bool, optional Whether to convert the data to the SI unit system. The default is ``False``. Returns ------- list List of the data in the database for the expression. """ if not expression: expression = self.active_expression if self.enable_pandas_output: return 20 * np.log10(self.data_magnitude(expression, convert_to_SI)) return [db20(i) for i in self.data_magnitude(expression, convert_to_SI)] @pyaedt_function_handler() def data_phase(self, expression=None, radians=True): """Retrieve the phase part of the data for an expression. Parameters ---------- expression : str, None Name of the expression. The default is ``None``, in which case the active expression is used. radians : bool, optional Whether to convert the data into radians or degree. The default is ``True`` for radians. Returns ------- list Phase data for the expression. """ if not expression: expression = self.active_expression coefficient = 1 if not radians: coefficient = 180 / math.pi if self.enable_pandas_output: return coefficient * np.arctan2(self.data_imag(expression), self.data_real(expression)) return [coefficient * math.atan2(k, i) for i, k in zip(self.data_real(expression), self.data_imag(expression))] @property def primary_sweep_values(self): """Retrieve the primary sweep for a given data and primary variable. Returns ------- list List of the primary sweep valid points for the expression. """ if self.enable_pandas_output: return pd.Series(self.variation_values(self.primary_sweep), dtype=object) return self.variation_values(self.primary_sweep) @property def primary_sweep_variations(self): """Retrieve the variations lists for a given primary variable. Returns ------- list List of the primary sweep valid points for the expression. """ expression = self.active_expression temp = self._variation_tuple() solution_data = list(self._solutions_real[expression].keys()) sol = [] position = list(self._sweeps_names).index(self.primary_sweep) for el in self.primary_sweep_values: temp[position] = el if self.__get_index(temp) in solution_data: sol_dict = {} i = 0 for sn in self._sweeps_names: sol_dict[sn] = temp[i] i += 1 sol.append(sol_dict) else: sol.append(None) if self.enable_pandas_output: return pd.Series(sol, dtype=object) return sol @pyaedt_function_handler() def data_real(self, expression=None, convert_to_SI=False): """Retrieve the real part of the data for an expression. Parameters ---------- expression : str, None Name of the expression. The default is ``None``, in which case the active expression is used. convert_to_SI : bool, optional Whether to convert the data to the SI unit system. The default is ``False``. Returns ------- list List of the real data for the expression. """ if not expression: expression = self.active_expression temp = self._variation_tuple() solution_data = self._solutions_real[expression] sol = [] position = list(self._sweeps_names).index(self.primary_sweep) sw = self.variation_values(self.primary_sweep) for el in sw: temp[position] = el try: sol.append(solution_data[self.__get_index(temp)]) except KeyError: sol.append(None) if convert_to_SI and self._quantity(self.units_data[expression]): sol = self._convert_list_to_SI( sol, self._quantity(self.units_data[expression]), self.units_data[expression] ) if self.enable_pandas_output: return pd.Series(sol) return sol @pyaedt_function_handler() def data_imag(self, expression=None, convert_to_SI=False): """Retrieve the imaginary part of the data for an expression. Parameters ---------- expression : str, optional Name of the expression. The default is ``None``, in which case the active expression is used. convert_to_SI : bool, optional Whether to convert the data to the SI unit system. The default is ``False``. Returns ------- list List of the imaginary data for the expression. """ if not expression: expression = self.active_expression temp = self._variation_tuple() solution_data = self._solutions_imag[expression] sol = [] position = list(self._sweeps_names).index(self.primary_sweep) sw = self.variation_values(self.primary_sweep) for el in sw: temp[position] = el try: sol.append(solution_data[self.__get_index(temp)]) except KeyError: sol.append(None) if convert_to_SI and self._quantity(self.units_data[expression]): sol = self._convert_list_to_SI( sol, self._quantity(self.units_data[expression]), self.units_data[expression] ) if self.enable_pandas_output: return pd.Series(sol) return sol @pyaedt_function_handler() def is_real_only(self, expression=None): """Check if the expression has only real values or not. Parameters ---------- expression : str, optional Name of the expression. The default is ``None``, in which case the active expression is used. Returns ------- bool ``True`` if the Solution Data for specific expression contains only real values. """ if not expression: expression = self.active_expression if self.enable_pandas_output: return True if self._solutions_imag[expression].abs().sum() > 0.0 else False for v in list(self._solutions_imag[expression].values()): if float(v) != 0.0: return False return True @pyaedt_function_handler() def export_data_to_csv(self, output, delimiter=";"): """Save to output csv file the Solution Data. Parameters ---------- output : str, Full path to csv file. delimiter : str, CSV Delimiter. Default is ``";"``. Returns ------- bool ``True`` when successful, ``False`` when failed. """ header = [] des_var = self._original_data[0].GetDesignVariableNames() sweep_var = self._original_data[0].GetSweepNames() for el in self._sweeps_names: unit = "" if el in des_var: unit = self._original_data[0].GetDesignVariableUnits(el) elif el in sweep_var: unit = self._original_data[0].GetSweepUnits(el) if unit == "": header.append(f"{el}") else: header.append(f"{el} [{unit}]") # header = [el for el in self._sweeps_names] for el in self.expressions: data_unit = self._original_data[0].GetDataUnits(el) if data_unit: data_unit = f" [{data_unit}]" if not self.is_real_only(el): header.append(el + f" (Real){data_unit}") header.append(el + f" (Imag){data_unit}") else: header.append(el + f"{data_unit}") list_full = [header] for e, v in self._solutions_real[self.active_expression].items(): e = [float(i) for i in e] list_full.append(list(e)) for el in self.expressions: i = 1 for e, v in self._solutions_real[el].items(): list_full[i].extend([v]) i += 1 i = 1 if not self.is_real_only(el): for e, v in self._solutions_imag[el].items(): list_full[i].extend([v]) i += 1 return write_csv(output, list_full, delimiter=delimiter) @pyaedt_function_handler() def _get_data_formula(self, curve, formula=None): if not formula or formula == "re": return self.data_real(curve) elif formula == "im": return self.data_imag(curve) elif formula == "db20": return self.data_db20(curve) elif formula == "db10": return self.data_db10(curve) elif formula == "mag": return self.data_magnitude(curve) elif formula == "phasedeg": return curve elif formula == "phaserad": return self.data_phase(curve, True) @pyaedt_function_handler() def get_report_plotter(self, curves=None, formula=None, to_radians=False, props=None): """Get the `ReportPlotter` on the specified curves. Parameters ---------- curves : list, str, optional Trace names. formula : str, optional Trace formula. Default is `None` which takes the real part of the trace. to_radians : bool, optional Whether is data has to be converted to radians or not. Default is ``False``. Returns ------- :class:`ansys.aedt.core.visualization.plot.matplotlib.ReportPlotter` Report plotter class. """ from ansys.aedt.core.visualization.plot.matplotlib import ReportPlotter if not curves: curves = self.expressions if isinstance(curves, str): curves = [curves] # if not formula: # formula = "mag" if to_radians: sw = self.to_radians(self.primary_sweep_values) else: sw = self.primary_sweep_values new = ReportPlotter() for curve in curves: if props is None: props = {"x_label": self.primary_sweep, "y_label": ""} active_intr = ",".join([f"{i}={k}" for i, k in self.active_intrinsic.items() if i != self.primary_sweep]) if formula: name = f"{formula}({curve})_{active_intr}" else: name = f"({curve})_{active_intr}" new.add_trace([sw, self._get_data_formula(curve, formula)], name=name, properties=props) return new @pyaedt_function_handler(math_formula="formula", xlabel="x_label", ylabel="y_label") def plot( self, curves=None, formula=None, size=(1920, 1440), show_legend=True, x_label="", y_label="", title="", snapshot_path=None, is_polar=False, show=True, ): """Create a matplotlib figure based on a list of data. Parameters ---------- curves : list Curves to be plotted. The default is ``None``, in which case the first curve is plotted. formula : str , optional Mathematical formula to apply to the plot curve. The default is ``None``, in which case only real value of the data stored in the solution data is plotted. Options are ``"abs"``, ``"db10"``, ``"db20"``, ``"im"``, ``"mag"``, ``"phasedeg"``, ``"phaserad"``, and ``"re"``. size : tuple, optional Image size in pixels (width, height). show_legend : bool Whether to show the legend. The default is ``True``. This parameter is ignored if the number of curves to plot is greater than 15. x_label : str Plot X label. y_label : str Plot Y label. title : str Plot title label. snapshot_path : str Full path to image file if a snapshot is needed. is_polar : bool, optional Set to `True` if this is a polar plot. show : bool, optional Whether if show the plot or not. Default is set to `True`. Returns ------- :class:`ansys.aedt.core.visualization.plot.matplotlib.ReportPlotter` Matplotlib class object. """ props = {"x_label": x_label, "y_label": y_label} if "Phi" in self.units_sweeps.keys() and is_polar: if self.units_sweeps["Phi"] == "deg": to_radians = False else: to_radians = True elif "Theta" in self.units_sweeps.keys() and is_polar: if self.units_sweeps["Theta"] == "deg": to_radians = False else: to_radians = True elif is_polar: to_radians = True else: to_radians = False report_plotter = self.get_report_plotter(curves=curves, formula=formula, to_radians=to_radians, props=props) report_plotter.show_legend = show_legend report_plotter.title = title report_plotter.size = size if is_polar: return report_plotter.plot_polar(snapshot_path=snapshot_path, show=show) else: return report_plotter.plot_2d(snapshot_path=snapshot_path, show=show) @pyaedt_function_handler( xlabel="x_label", ylabel="y_label", math_formula="formula", x_axis="primary_sweep", y_axis="secondary_sweep" ) def plot_3d( self, curve=None, primary_sweep="Theta", secondary_sweep="Phi", x_label="", y_label="", title="", formula=None, size=(1920, 1440), snapshot_path=None, show=True, ): """Create a matplotlib 3D figure based on a list of data. Parameters ---------- curve : str Curve to be plotted. If None, the first curve will be plotted. primary_sweep : str, optional Primary sweep variable. The default is ``"Theta"``. secondary_sweep : str, optional Secondary sweep variable. The default is ``"Phi"``. x_label : str Plot X label. y_label : str Plot Y label. title : str Plot title label. formula : str , optional Mathematical formula to apply to the plot curve. The default is ``None``. Options are `"abs"``, ``"db10"``, ``"db20"``, ``"im"``, ``"mag"``, ``"phasedeg"``, ``"phaserad"``, and ``"re"``. size : tuple, optional Image size in pixels (width, height). The default is ``(2000, 1000)``. snapshot_path : str, optional Full path to image file if a snapshot is needed. The default is ``None``. show : bool, optional Whether if show the plot or not. Default is set to `True`. Returns ------- :class:`matplotlib.figure.Figure` Matplotlib figure object. """ from ansys.aedt.core.visualization.plot.matplotlib import ReportPlotter if self.primary_sweep == "Phi": primary_sweep = "Phi" secondary_sweep = "Theta" elif self.primary_sweep == "Theta": primary_sweep = "Theta" secondary_sweep = "Phi" if not curve: curve = self.active_expression if not formula: if curve[0:2].lower() == "db": formula = "re" # Avoid taking magnitude for db traces. else: formula = "mag" primary_radians = [i * math.pi / 180 for i in self.variation_values(primary_sweep)] secondary_values = self.variation_values(secondary_sweep) secondary_radians = [] r = [] for el in secondary_values: if secondary_sweep in self.active_intrinsic: self.active_intrinsic[secondary_sweep] = el else: self.active_variation[secondary_sweep] = el secondary_radians.append(el * math.pi / 180) if formula.lower() == "re": r.append(self.data_real(curve)) elif formula.lower() == "im": r.append(self.data_imag(curve)) elif formula.lower() == "db20": r.append(self.data_db20(curve)) elif formula.lower() == "db10": r.append(self.data_db10(curve)) elif formula.lower() == "mag": r.append(self.data_magnitude(curve)) elif formula == "phasedeg": r.append(self.data_phase(curve, False)) elif formula == "phaserad": r.append(self.data_phase(curve, True)) min_r = 1e12 max_r = -1e12 if self.enable_pandas_output: for el in r: min_r = min(min_r, el.min()) max_r = max(max_r, el.max()) else: for el in r: min_r = min(min_r, min(el)) max_r = max(max_r, max(el)) if min_r < 0: r = [i + np.abs(min_r) for i in r] primary_grid, secondary_grid = np.meshgrid(primary_radians, secondary_radians) r_grid = np.reshape(r, (len(secondary_radians), len(primary_radians))) if self.primary_sweep == "Phi": phi_grid = primary_grid theta_grid = secondary_grid else: phi_grid = secondary_grid theta_grid = primary_grid x = r_grid * np.sin(theta_grid) * np.cos(phi_grid) y = r_grid * np.sin(theta_grid) * np.sin(phi_grid) z = r_grid * np.cos(theta_grid) data_plot = [x, y, z] if not x_label: x_label = "Phi" if not y_label: y_label = "Theta" if not title: title = "Polar Far-Field" new = ReportPlotter() new.size = size new.show_legend = False new.title = title props = {"x_label": x_label, "y_label": y_label} new.add_trace(data_plot, 0, props, curve) _ = new.plot_3d(trace=0, snapshot_path=snapshot_path, show=show, color_map_limits=[min_r, max_r]) return new @pyaedt_function_handler() def ifft(self, curve_header="NearE", u_axis="_u", v_axis="_v", window=False): """Create IFFT of given complex data. Parameters ---------- curve_header : curve header. Solution data must contain 3 curves with X, Y and Z components of curve header. u_axis : str, optional U Axis name. Default is Hfss name "_u" v_axis : str, optional V Axis name. Default is Hfss name "_v" window : bool, optional Either if Hanning windowing has to be applied. Returns ------- List IFFT Matrix. """ u = self.variation_values(u_axis) v = self.variation_values(v_axis) freq = self.variation_values("Freq") if self.enable_pandas_output: e_real_x = np.reshape(self._solutions_real[curve_header + "X"].copy().values, (len(freq), len(v), len(u))) e_imag_x = np.reshape(self._solutions_imag[curve_header + "X"].copy().values, (len(freq), len(v), len(u))) e_real_y = np.reshape(self._solutions_real[curve_header + "Y"].copy().values, (len(freq), len(v), len(u))) e_imag_y = np.reshape(self._solutions_imag[curve_header + "Y"].copy().values, (len(freq), len(v), len(u))) e_real_z = np.reshape(self._solutions_real[curve_header + "Z"].copy().values, (len(freq), len(v), len(u))) e_imag_z = np.reshape(self._solutions_imag[curve_header + "Z"].copy().values, (len(freq), len(v), len(u))) else: vals_e_real_x = [j for j in self._solutions_real[curve_header + "X"].values()] vals_e_imag_x = [j for j in self._solutions_imag[curve_header + "X"].values()] vals_e_real_y = [j for j in self._solutions_real[curve_header + "Y"].values()] vals_e_imag_y = [j for j in self._solutions_imag[curve_header + "Y"].values()] vals_e_real_z = [j for j in self._solutions_real[curve_header + "Z"].values()] vals_e_imag_z = [j for j in self._solutions_imag[curve_header + "Z"].values()] e_real_x = np.reshape(vals_e_real_x, (len(freq), len(v), len(u))) e_imag_x = np.reshape(vals_e_imag_x, (len(freq), len(v), len(u))) e_real_y = np.reshape(vals_e_real_y, (len(freq), len(v), len(u))) e_imag_y = np.reshape(vals_e_imag_y, (len(freq), len(v), len(u))) e_real_z = np.reshape(vals_e_real_z, (len(freq), len(v), len(u))) e_imag_z = np.reshape(vals_e_imag_z, (len(freq), len(v), len(u))) temp_e_comp_x = e_real_x.astype("float64") + complex(0, 1) * e_imag_x.astype("float64") temp_e_comp_y = e_real_y.astype("float64") + complex(0, 1) * e_imag_y.astype("float64") temp_e_comp_z = e_real_z.astype("float64") + complex(0, 1) * e_imag_z.astype("float64") e_comp_x = np.zeros((len(freq), len(v), len(u)), dtype=np.complex128) e_comp_y = np.zeros((len(freq), len(v), len(u)), dtype=np.complex128) e_comp_z = np.zeros((len(freq), len(v), len(u)), dtype=np.complex128) if window: timewin = np.hanning(len(freq)) for row in range(0, len(v)): for col in range(0, len(u)): e_comp_x[:, row, col] = np.multiply(temp_e_comp_x[:, row, col], timewin) e_comp_y[:, row, col] = np.multiply(temp_e_comp_y[:, row, col], timewin) e_comp_z[:, row, col] = np.multiply(temp_e_comp_z[:, row, col], timewin) else: e_comp_x = temp_e_comp_x e_comp_y = temp_e_comp_y e_comp_z = temp_e_comp_z e_time_x = np.fft.ifft(np.fft.fftshift(e_comp_x, 0), len(freq), 0, None) e_time_y = np.fft.ifft(np.fft.fftshift(e_comp_y, 0), len(freq), 0, None) e_time_z = np.fft.ifft(np.fft.fftshift(e_comp_z, 0), len(freq), 0, None) e_time = np.zeros((np.size(freq), np.size(v), np.size(u))) for i in range(0, len(freq)): e_time[i, :, :] = np.abs( np.sqrt(np.square(e_time_x[i, :, :]) + np.square(e_time_y[i, :, :]) + np.square(e_time_z[i, :, :])) ) self._ifft = e_time return self._ifft @pyaedt_function_handler(csv_dir="csv_path", name_str="csv_file_header") def ifft_to_file( self, u_axis="_u", v_axis="_v", coord_system_center=None, db_val=False, num_frames=None, csv_path=None, csv_file_header="res_", ): """Save IFFT matrix to a list of CSV files (one per time step). Parameters ---------- u_axis : str, optional U Axis name. Default is Hfss name "_u" v_axis : str, optional V Axis name. Default is Hfss name "_v" coord_system_center : list, optional List of UV GlobalCS Center. db_val : bool, optional Whether data must be exported into a database. The default is ``False``. num_frames : int, optional Number of frames to export. The default is ``None``. csv_path : str, optional Output path. The default is ``None``. csv_file_header : str, optional CSV file header. The default is ``"res_"``. Returns ------- str Path to file containing the list of csv files. """ if not coord_system_center: coord_system_center = [0, 0, 0] t_matrix = self._ifft x_c_list = [float(i) for i in self.variation_values(u_axis)] y_c_list = [float(i) for i in self.variation_values(v_axis)] adj_x = coord_system_center[0] adj_y = coord_system_center[1] adj_z = coord_system_center[2] if num_frames: frames = num_frames else: frames = t_matrix.shape[0] csv_list = [] if os.path.exists(csv_path): files = [os.path.join(csv_path, f) for f in os.listdir(csv_path) if csv_file_header in f and ".csv" in f] for file in files: os.remove(file) else: os.mkdir(csv_path) for frame in range(frames): output = os.path.join(csv_path, csv_file_header + str(frame) + ".csv") list_full = [["x", "y", "z", "val"]] for i, y in enumerate(y_c_list): for j, x in enumerate(x_c_list): y_coord = y + adj_y x_coord = x + adj_x z_coord = adj_z if db_val: val = 10.0 * np.log10(np.abs(t_matrix[frame, i, j])) else: val = t_matrix[frame, i, j] row_lst = [x_coord, y_coord, z_coord, val] list_full.append(row_lst) write_csv(output, list_full, delimiter=",") csv_list.append(output) txt_file_name = csv_path + "fft_list.txt" textfile = open_file(txt_file_name, "w") for element in csv_list: textfile.write(element + "\n") textfile.close() return txt_file_name 无法释放
最新发布
08-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值