-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathopenems_model_gen.h
324 lines (272 loc) · 11.4 KB
/
openems_model_gen.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/*****************************************************************************
* *
* Copyright (C) 2023 Liu An Lin <[email protected]> *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*****************************************************************************/
#ifndef __OPENEMS_MODEL_GEN_H__
#define __OPENEMS_MODEL_GEN_H__
#include <set>
#include <map>
#include <vector>
#include <memory>
#include "pcb.h"
class openems_model_gen
{
public:
enum
{
BC_MUR,
BC_PML,
};
struct point
{
point() : x(0), y(0), z(0) {}
point(float x, float y, float z) : x(x), y(y), z(z) {}
float x;
float y;
float z;
};
struct excitation
{
enum
{
DIR_X,
DIR_Y,
DIR_Z,
};
excitation()
: gen_mesh(true)
, dir(DIR_X)
, R(50)
, excite(true)
{
}
bool gen_mesh;
point start;
point end;
std::uint32_t dir;
float R;
bool excite;
};
struct lumped_element
{
enum
{
DIR_X,
DIR_Y,
DIR_Z,
};
enum
{
TYPE_R,
TYPE_L,
TYPE_C,
};
lumped_element()
: gen_mesh(true)
, dir(DIR_X)
, type(TYPE_R)
, v(50)
{
}
std::string name;
bool gen_mesh;
point start;
point end;
std::uint32_t dir;
std::uint32_t type;
float v;
};
struct mesh
{
enum
{
DIR_X,
DIR_Y,
DIR_Z,
};
struct line
{
line() : v(0), prio(0) {}
line(float v_, std::uint32_t prio_) : v(v_), prio(prio_) {}
float v;
std::uint32_t prio;
bool operator <(const line& b) const
{
return this->v < b.v;
}
};
struct line_range
{
line_range() : start(0), end(0), gap(0), prio(0) {}
line_range(float start_, float end_, float gap_, float prio_)
: start(start_), end(end_), gap(gap_), prio(prio_) {}
float start;
float end;
float gap;
std::uint32_t prio;
bool operator <(const line_range& other) const
{
return this->gap < other.gap;
}
};
std::set<line> x;
std::set<line> y;
std::set<line> z;
std::multiset<line_range> x_range;
std::multiset<line_range> y_range;
std::multiset<line_range> z_range;
};
private:
struct mesh_info
{
mesh_info()
: gen_mesh(true)
, use_uniform_grid(false)
, x_gap(false)
, y_gap(false)
, zone_gen_mesh(false)
, mesh_prio(0)
{
}
bool gen_mesh;
bool use_uniform_grid;
float x_gap;
float y_gap;
bool zone_gen_mesh;
std::uint32_t mesh_prio;
};
struct range_det
{
range_det()
: x_min(10000)
, x_max(-10000)
, y_min(10000)
, y_max(-10000)
{
}
void det(float x, float y)
{
x_min = std::min(x_min, x);
x_max = std::max(x_max, x);
y_min = std::min(y_min, y);
y_max = std::max(y_max, y);
}
bool is_valid()
{
return x_min != 10000 && x_max != -10000 && y_min != 10000 && y_max != -10000;
}
float x_min;
float x_max;
float y_min;
float y_max;
};
public:
openems_model_gen(const std::shared_ptr<pcb>& pcb);
~openems_model_gen();
public:
void add_net(std::uint32_t net_id, bool gen_mesh = true, bool zone_gen_mesh = false, std::uint32_t mesh_prio = 1);
void add_net(std::uint32_t net_id, float x_gap, float y_gap, bool zone_gen_mesh = false, std::uint32_t mesh_prio = 0);
void add_footprint(const std::string& fp_ref, bool gen_mesh = true, std::uint32_t mesh_prio = 2);
void add_footprint(const std::string& fp_ref, float x_gap, float y_gap, std::uint32_t mesh_prio = 2);
void add_excitation(const std::string& fp1, const std::string& fp1_pad_number, const std::string& fp1_layer_name,
const std::string& fp2, const std::string& fp2_pad_number, const std::string& fp2_layer_name, std::uint32_t dir, float R = 50, bool gen_mesh = true);
void add_excitation(pcb::point start, const std::string& start_layer, pcb::point end, const std::string& end_layer, std::uint32_t dir, float R = 50, bool gen_mesh = true);
void add_lumped_port(const std::string& fp1, const std::string& fp1_pad_number, const std::string& fp1_layer_name,
const std::string& fp2, const std::string& fp2_pad_number, const std::string& fp2_layer_name,
std::uint32_t dir, float R, bool excite = false, bool gen_mesh = true);
void add_lumped_port(const std::string& fp_name, float R = -1, bool excite = false, bool gen_mesh = true);
void add_lumped_element(const std::string& fp1, const std::string& fp1_pad_number, const std::string& fp1_layer_name,
const std::string& fp2, const std::string& fp2_pad_number, const std::string& fp2_layer_name,
std::uint32_t dir, std::uint32_t type, float v, bool gen_mesh = true);
void add_lumped_element(const std::string& fp_name, bool gen_mesh = true);
void add_lumped_element(pcb::point start, const std::string& start_layer, pcb::point end, const std::string& end_layer, std::uint32_t dir, std::uint32_t type, float v, bool gen_mesh = true);
void add_freq(float freq);
void add_mesh_range(float start, float end, float gap, std::uint32_t dir = mesh::DIR_X, std::uint32_t prio = 1);
void set_mesh_lambda_ratio(float ratio) { _lambda_mesh_ratio = ratio; }
void set_boundary_cond(std::uint32_t bc);
void set_end_criteria(float end_criteria_db) { _end_criteria_db = end_criteria_db; }
void set_nf2ff_footprint(const std::string& fp);
void set_excitation_freq(float f0, float fc);
void set_far_field_freq(float freq);
void set_mesh_min_gap(float x_min_gap = 0.1, float y_min_gap = 0.1, float z_min_gap = 0.01);
void gen_model(const std::string& func_name);
void gen_mesh(const std::string& func_name);
void gen_antenna_simulation_scripts(const std::string& prefix);
void gen_sparameter_scripts(const std::string& prefix);
private:
void _gen_mesh_z(FILE *fp);
void _gen_mesh_xy(FILE *fp);
void _add_dielectric(FILE *fp);
void _add_metal(FILE *fp);
void _add_segment(FILE *fp, std::int32_t metal_prio = 1);
void _add_via(FILE *fp, std::int32_t metal_prio = 1);
void _add_zone(FILE *fp, std::int32_t metal_prio = 1);
void _add_footprint(FILE *fp, std::int32_t metal_prio = 1, std::int32_t metal_pad_prio = 1);
void _add_gr(const pcb::gr& gr, pcb::point at, float angle, const std::string& name, FILE *fp, range_det& range, std::uint32_t mesh_prio = 0, bool gen_mesh = true, std::int32_t metal_prio = 1);
void _add_pad(const pcb::footprint& footprint, const pcb::pad& p, const std::string& name, FILE *fp, range_det& range, std::uint32_t mesh_prio = 0, bool gen_mesh = true, std::int32_t metal_prio = 1);
void _add_line(FILE *fp, const std::string& name, const pcb::point& start, const pcb::point& end, float width, float z1, float z2,
range_det& range, bool gen_mesh, bool use_uniform_grid, std::uint32_t mesh_prio, std::int32_t metal_prio = 1);
void _add_arc(FILE *fp, const std::string& name, const pcb::point& start, const pcb::point& mid, const pcb::point& end, float width, float z1, float z2,
range_det& range, bool gen_mesh, bool use_uniform_grid, std::uint32_t mesh_prio, std::int32_t metal_prio = 1);
void _add_excitation(FILE *fp, std::uint32_t mesh_prio = 99);
void _add_lumped_element(FILE *fp, std::uint32_t mesh_prio = 99);
void _add_nf2ff_box(FILE *fp, std::uint32_t mesh_prio = 0);
void _add_read_ui(FILE *fp);
void _add_plot_time_domain_voltage(FILE *fp);
void _add_plot_feed_point_impedance(FILE *fp);
void _add_plot_s11(FILE *fp);
void _add_plot_mult_port_sparameter(FILE *fp);
void _add_plot_vswr(FILE *fp);
void _add_plot_far_field(FILE *fp);
void _add_write_snp(FILE *fp);
/* return 100000 失败 */
float _get_mesh_x_gap(float x);
float _get_mesh_y_gap(float y);
float _get_mesh_gap(float v, const std::multiset<mesh::line_range>& mesh_line_range);
void _apply_mesh_line_range(mesh& mesh);
void _apply_mesh_line_range(std::set<mesh::line>& mesh_line, const std::multiset<mesh::line_range>& mesh_line_range);
void _clean_mesh_line(std::set<mesh::line>& mesh_line, float min_gap = 0.01);
void _smooth_mesh_line(std::set<mesh::line>& mesh_line, float min_gap, float max_gap, float ratio);
bool _smooth_add_line(std::list<mesh::line>& mesh_line_list, float min_gap, float max_gap, float ratio, float dir = 1);
bool _smooth_line(std::list<mesh::line>& mesh_line_list);
void _check_mesh(const std::set<mesh::line>& mesh_line);
std::vector<pcb::point> _get_fp_poly_points(const pcb::footprint& fp, const std::string& pad_number);
float _round_xy(float v);
float _suffix_to_value(const std::string& suffix);
float _string_to_float(const std::string& str);
private:
std::shared_ptr<pcb> _pcb;
std::map<std::uint32_t, mesh_info> _nets;
std::map<std::string, mesh_info> _footprints;
std::vector<float> _freq;
mesh _mesh;
float _mesh_x_min_gap;
float _mesh_y_min_gap;
float _mesh_z_min_gap;
float _lambda_mesh_ratio;
float _pix_unit;
bool _ignore_cu_thickness;
std::uint32_t _bc;
float _end_criteria_db;
float _f0;
float _fc;
float _far_field_freq;
std::string _nf2ff_fp;
std::vector<excitation> _excitations;
std::vector<lumped_element> _lumped_elements;
static float C0;
};
#endif