优化端口传递物性参数方式,减少上下游元件重复计算量
This commit is contained in:
1 parent
91bd9fb252
commit
5d5a2e1843
12 files changed
+773
-65
No files matched your search
@@ -260,7 +260,7 @@ def _compile_storage_anchored_program(network: SimulationNetwork) -> NativeProgr
|
||||
initial_volume = max(base, c.cvol0 / 100) if c.model_type == "amesim_pnch012" else base
|
||||
init.append(f"if (!native_gas_init({_number(c.p0)}, {_number(c.T0)}, {_number(initial_volume)}, &y[{si(c, 'm')}])) return 0;")
|
||||
lines.append(f"NativeGas gas_{gi};")
|
||||
lines.append(f"if (!native_gas(y[{si(c, 'm')}], y[{si(c, 'U')}], {volume}, &gas_{gi})) return 0;")
|
||||
lines.append(f"if (!native_gas_context(properties, y[{si(c, 'm')}], y[{si(c, 'U')}], {volume}, &gas_{gi})) return 0;")
|
||||
for field in ("m", "U"):
|
||||
put(c, field, f"y[{si(c, field)}]")
|
||||
for field in ("p", "T", "rho", "u", "h"):
|
||||
@@ -277,7 +277,7 @@ def _compile_storage_anchored_program(network: SimulationNetwork) -> NativeProgr
|
||||
continue
|
||||
a, b = chamber_at(c, "port_2"), chamber_at(c, "port_3")
|
||||
put(c, "xv", f"fmax(0.0, fmin(1.0, {get(c, 'res.signal')}))")
|
||||
lines.append(f"if (!native_orifice({get(a, 'p')}, {get(b, 'p')}, {get(a, 'h')}, {get(b, 'h')}, {_number(c.effective_cq * c.maximum_area)}, {get(c, 'xv')}, &{get(c, 'port_2.m_flow')}, &{get(c, 'cm')}, &{get(c, 'gasvel')})) return 0;")
|
||||
lines.append(f"if (!native_orifice_context(properties, {get(a, 'p')}, {get(b, 'p')}, {get(a, 'h')}, {get(b, 'h')}, {_number(c.effective_cq * c.maximum_area)}, {get(c, 'xv')}, &{get(c, 'port_2.m_flow')}, &{get(c, 'cm')}, &{get(c, 'gasvel')})) return 0;")
|
||||
assigned.update((key(c, "cm"), key(c, "gasvel")))
|
||||
put(c, "port_3.m_flow", f"-{get(c, 'port_2.m_flow')}")
|
||||
put(c, "port_2.h_outflow", get(b, "h"))
|
||||
@@ -368,7 +368,10 @@ def _compile_storage_anchored_program(network: SimulationNetwork) -> NativeProgr
|
||||
f"const double model_atol[NSTATES] = {{{','.join(map(state_absolute_tolerance, state_keys))}}};",
|
||||
"const char *const model_output_keys[NOUTPUTS] = {" + ",".join(json.dumps(v.key, ensure_ascii=True) for v in variables) + "};",
|
||||
"int model_init(double *y) {", *init, "return 1; }",
|
||||
"int model_eval(double t, const double *y, double *dy, double *w) {", "(void)t;", *lines,
|
||||
"int model_eval(double t, const double *y, double *dy, double *w) {", "(void)t;",
|
||||
f"NativePropertyState property_states[{min(256,max(16,4*len(components)))}];",
|
||||
"NativePropertyCache property_cache, *properties=&property_cache;",
|
||||
"native_properties_init(properties,property_states,sizeof(property_states)/sizeof(property_states[0]));", *lines,
|
||||
"for (int i=0;i<NSTATES;i++) if (!isfinite(dy[i])) return 0;",
|
||||
"for (int i=0;i<NOUTPUTS;i++) if (!isfinite(w[i])) return 0;",
|
||||
"return 1; }",
|
||||
|
||||
@@ -268,7 +268,7 @@ def compile_extended_program(network):
|
||||
if kind=='amesim_pnch012' else
|
||||
c.cvol if kind=='amesim_pnch023' else c.V if kind in ('cylinder','tank') else c.volume)
|
||||
gas_initializers.append(f'if(!native_medium_init({medium(c)},{num(p0)},{num(T0)},{num(initial_volume)},{int(kind in ("cylinder","tank"))},&y[{states[c.name,"m"+suffix]}])) return 0;')
|
||||
lines.append(f'if(!native_medium_gas({medium(c)}, {y(c,"m"+suffix)}, {y(c,"U"+suffix)}, {V}, &{gas})) return 0;')
|
||||
lines.append(f'if(!native_medium_gas_context(properties,{medium(c)}, {y(c,"m"+suffix)}, {y(c,"U"+suffix)}, {V}, &{gas})) return 0;')
|
||||
for field in ('m', 'U'):
|
||||
put(c, field+suffix, y(c, field+suffix))
|
||||
for field in ('p','T','rho','u','h'):
|
||||
@@ -312,7 +312,7 @@ def compile_extended_program(network):
|
||||
pipe_cache_count = 0
|
||||
def pipe_flow(expression):
|
||||
nonlocal pipe_cache_count
|
||||
result = f'native_pipe_flow_cached(&pipe_cache[{pipe_cache_count}],{expression})'
|
||||
result = f'native_pipe_flow_cached_context(properties,&pipe_cache[{pipe_cache_count}],{expression})'
|
||||
pipe_cache_count += 1
|
||||
return result
|
||||
def flow(c, name, expr):
|
||||
@@ -339,9 +339,9 @@ def compile_extended_program(network):
|
||||
flow(c,a,f'{num(c.K_eff)}*copysign(sqrt(fabs({pa}-{pb})),{pa}-{pb})')
|
||||
elif kind=='pipe':
|
||||
resistance=c.lambda_darcy*c.L/c.D
|
||||
flow(c,a,f'copysign(sqrt(fabs({pa}-{pb})*2*fmax(native_density({medium(c)},fmax(.5*({pa}+{pb}),1),{num(c.T0)}),1e-12)*{num(c.area*c.area/resistance)}),{pa}-{pb})')
|
||||
flow(c,a,f'copysign(sqrt(fabs({pa}-{pb})*2*fmax(native_density_context(properties,{medium(c)},fmax(.5*({pa}+{pb}),1),{num(c.T0)}),1e-12)*{num(c.area*c.area/resistance)}),{pa}-{pb})')
|
||||
elif kind=='amesim_pnl00r':
|
||||
T=f'native_temperature_ph({medium(c)},fmax(fmax({pa},{pb}),1),{pa}>={pb}?{hin(c,a,True)}:{hin(c,b,True)})'
|
||||
T=f'native_temperature_ph_context(properties,{medium(c)},fmax(fmax({pa},{pb}),1),{pa}>={pb}?{hin(c,a,True)}:{hin(c,b,True)})'
|
||||
flow(c,a,pipe_flow(f'{medium(c)},{pa},{pb},{T},{num(c.diam)},{num(c.le)},{num(c.rr)},0'))
|
||||
else:
|
||||
opening = w(c,'xv') if kind!='amesim_pnor001' else '1.0'
|
||||
@@ -351,7 +351,7 @@ def compile_extended_program(network):
|
||||
area = c.effective_cq*(c.effective_area if kind=='amesim_pnor001' else c.maximum_area)
|
||||
inputs=f'{medium(c)},{pa},{pb},{hin(c,a)},{hin(c,b)},{num(area)},{opening}'
|
||||
outputs=(q(c,a),w(c,'cm'),w(c,'gasvel'))
|
||||
code=f'if(!native_medium_orifice({inputs},&{outputs[0]},&{outputs[1]},&{outputs[2]})) return 0;'
|
||||
code=f'if(!native_medium_orifice_context(properties,{inputs},&{outputs[0]},&{outputs[1]},&{outputs[2]})) return 0;'
|
||||
operations.append(Computation(f'flow:{c.name}.{a}',outputs,references(inputs),(code,)))
|
||||
flow_known.add(q(c,a));assigned.update((c.name+'.cm',c.name+'.gasvel'))
|
||||
flow(c,b,f'-{q(c,a)}')
|
||||
@@ -360,7 +360,7 @@ def compile_extended_program(network):
|
||||
for name in (['port_1'] if kind.endswith('1') else names):
|
||||
# Resistance uses the gas arriving from the upstream side,
|
||||
# including inflow into a PNL0001 storage volume.
|
||||
T=f'({p(c,name)}>{gas}.p?native_temperature_ph({medium(c)},fmax({p(c,name)},1),{hin(c,name,True)}):{gas}.T)'
|
||||
T=f'({p(c,name)}>{gas}.p?native_temperature_ph_context(properties,{medium(c)},fmax({p(c,name)},1),{hin(c,name,True)}):{gas}.T)'
|
||||
flow(c,name,pipe_flow(f'{medium(c)},{p(c,name)},{gas}.p,{T},{num(c.diam)},{num(c.le/(2 if kind.endswith("2") else 1))},{num(c.rr)},1'))
|
||||
for edge in network.connections:
|
||||
if edge.domain=='pneumatic':
|
||||
@@ -513,7 +513,7 @@ def compile_extended_program(network):
|
||||
if kind=='amesim_pnl0003':
|
||||
a,b=gases[c.name,1],gases[c.name,2]
|
||||
center=w(c,'dmctr')
|
||||
put(c,'dmctr',f'native_pipe_flow({medium(c)},{a}.p,{b}.p,{a}.p>={b}.p?{a}.T:{b}.T,{num(c.diam)},{num(c.le)},{num(c.rr)},3)')
|
||||
put(c,'dmctr',f'native_pipe_flow_context(properties,{medium(c)},{a}.p,{b}.p,{a}.p>={b}.p?{a}.T:{b}.T,{num(c.diam)},{num(c.le)},{num(c.rr)},3)')
|
||||
for half in halves:
|
||||
gas=gases[c.name,half];suffix=str(half) if half else ''
|
||||
names=['port_'+suffix] if half else pnames(c)
|
||||
@@ -536,7 +536,7 @@ def compile_extended_program(network):
|
||||
gas=gases[c.name,0]
|
||||
for name in pnames(c):
|
||||
flow=q(c,name);pp=f'({flow}>=0?fmax({p(c,name)},1):fmax({gas}.p,1))'
|
||||
temp=f'({flow}>=0?fmax(native_temperature_ph({medium(c)},{pp},{hin(c,name,True)}),1):{gas}.T)'
|
||||
temp=f'({flow}>=0?fmax(native_temperature_ph_context(properties,{medium(c)},{pp},{hin(c,name,True)}),1):{gas}.T)'
|
||||
diag.append((flow,pp,temp,c.le/2,0))
|
||||
elif kind=='amesim_pnl0003':
|
||||
a,b=gases[c.name,1],gases[c.name,2];flow=w(c,'dmctr')
|
||||
@@ -545,13 +545,13 @@ def compile_extended_program(network):
|
||||
pa,pb=p(c,'port_1'),p(c,'port_2');pp=f'fmax(fmax({pa},{pb}),1)'
|
||||
if kind=='amesim_pnl0001':
|
||||
gas=gases[c.name,0]
|
||||
temp=f'({pa}>{gas}.p?fmax(native_temperature_ph({medium(c)},{pp},{hin(c,"port_1",True)}),1):{gas}.T)'
|
||||
temp=f'({pa}>{gas}.p?fmax(native_temperature_ph_context(properties,{medium(c)},{pp},{hin(c,"port_1",True)}),1):{gas}.T)'
|
||||
else:
|
||||
temp=f'fmax(native_temperature_ph({medium(c)},{pp},{pa}>={pb}?{hin(c,"port_1",True)}:{hin(c,"port_2",True)}),1)'
|
||||
temp=f'fmax(native_temperature_ph_context(properties,{medium(c)},{pp},{pa}>={pb}?{hin(c,"port_1",True)}:{hin(c,"port_2",True)}),1)'
|
||||
diag=[(q(c,'port_1'),pp,temp,c.le,0)]
|
||||
lines.append('{ double d[4],acc[4]={0};')
|
||||
for flow,pp,temp,length,diagnostic in diag:
|
||||
lines.append(f'native_pipe_diagnostics({medium(c)},{flow},{pp},{temp},{num(c.diam)},{num(length)},{num(c.rr)},{diagnostic},d);')
|
||||
lines.append(f'native_pipe_diagnostics_context(properties,{medium(c)},{flow},{pp},{temp},{num(c.diam)},{num(length)},{num(c.rr)},{diagnostic},d);')
|
||||
if len(diag)>1: lines.append('d[2]=fabs(d[2]);')
|
||||
lines.append('for(int i=0;i<4;i++) acc[i]+=d[i];')
|
||||
for i,field in enumerate(('re','cm','v','ff')):
|
||||
@@ -574,6 +574,9 @@ def compile_extended_program(network):
|
||||
*schedule_helpers,
|
||||
'int model_init(double *y) {',*[f'y[{i}]={num(v)};' for i,v in enumerate(initial)],*gas_initializers,'return 1;}',
|
||||
'int model_eval(double t,const double *y,double *dy,double *w) {',
|
||||
f'NativePropertyState property_states[{min(256,max(16,4*gas_count+2*len(components)))}];',
|
||||
'NativePropertyCache property_cache, *properties=&property_cache;',
|
||||
'native_properties_init(properties,property_states,sizeof(property_states)/sizeof(property_states[0]));',
|
||||
*(['double projected[NSTATES];for(int i=0;i<NSTATES;i++) projected[i]=y[i];',*project,'y=projected;'] if project else []),
|
||||
f'double p[{np}]={{0}},h[{nq}]={{0}},q[{nq}]={{0}};NativeGas g[{ng}];',
|
||||
f'double fb[{max(1,flow_temporary_count)}]={{0}};(void)fb;',
|
||||
|
||||
@@ -185,9 +185,9 @@ class EvaluationSchedule:
|
||||
closure; a pressure trial further restricts work to its residual inputs.
|
||||
"""
|
||||
helpers, lines = [], []
|
||||
args = 'p,h,g,w,q,fb,pipe_cache'
|
||||
args = 'p,h,g,w,q,fb,pipe_cache,properties'
|
||||
signature = ('double *p,double *h,const NativeGas *g,double *w,double *q,'
|
||||
'double *fb,NativePipeCache *pipe_cache')
|
||||
'double *fb,NativePipeCache *pipe_cache,NativePropertyCache *properties')
|
||||
|
||||
def code(indices):
|
||||
return [line for i in indices for line in
|
||||
@@ -195,7 +195,7 @@ class EvaluationSchedule:
|
||||
|
||||
def helper(name, indices):
|
||||
helpers.extend([f'static int {name}({signature}) {{',
|
||||
'(void)p;(void)h;(void)g;(void)w;(void)q;(void)fb;(void)pipe_cache;',
|
||||
'(void)p;(void)h;(void)g;(void)w;(void)q;(void)fb;(void)pipe_cache;(void)properties;',
|
||||
*code(indices), 'return 1;', '}'])
|
||||
return f'if(!{name}({args})) return 0;'
|
||||
|
||||
|
||||
Reference in new issue
Block a user