Spaces:
Sleeping
Sleeping
Update app/construction.py
Browse files- app/construction.py +70 -19
app/construction.py
CHANGED
@@ -238,19 +238,24 @@ def display_constructions_tables(construction_library: ConstructionLibrary):
|
|
238 |
if category_str not in MaterialCategory.__members__:
|
239 |
st.error(f"Invalid category for material {material_name}: {library_material['category']}")
|
240 |
break
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
|
|
|
|
|
|
|
|
|
|
254 |
success, message = material_library.add_project_material(new_material, st.session_state.project_data["materials"]["project"])
|
255 |
if not success:
|
256 |
st.error(f"Failed to copy material '{material_name}': {message}")
|
@@ -339,7 +344,35 @@ def display_construction_editor(construction_library: ConstructionLibrary):
|
|
339 |
materials = get_available_materials()
|
340 |
material_objects = {name: m for name, m in materials.items() if isinstance(m, Material)}
|
341 |
if is_preview:
|
342 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
343 |
material_names = list(material_objects.keys())
|
344 |
|
345 |
if not material_names and not is_preview:
|
@@ -434,12 +467,23 @@ def display_construction_editor(construction_library: ConstructionLibrary):
|
|
434 |
material_name = layer.get("material_name")
|
435 |
thickness = layer.get("thickness", 0.1)
|
436 |
if material_name in material_objects:
|
437 |
-
material
|
438 |
-
|
|
|
439 |
if valid_layers:
|
440 |
-
|
441 |
-
|
442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
else:
|
444 |
st.warning("No valid materials selected for U-Value calculation.")
|
445 |
else:
|
@@ -501,6 +545,7 @@ def display_construction_editor(construction_library: ConstructionLibrary):
|
|
501 |
st.error(f"Failed to save construction: {message}")
|
502 |
except Exception as e:
|
503 |
st.error(f"Error saving construction: {str(e)}")
|
|
|
504 |
|
505 |
def calculate_construction_properties(layers: List[Dict[str, Any]], materials: Dict[str, Any]) -> Dict[str, float]:
|
506 |
"""
|
@@ -519,12 +564,16 @@ def calculate_construction_properties(layers: List[Dict[str, Any]], materials: D
|
|
519 |
# Thermal resistance
|
520 |
if material.conductivity > 0:
|
521 |
r_value += thickness / material.conductivity
|
|
|
|
|
522 |
# Thermal mass
|
523 |
thermal_mass += material.density * material.specific_heat * thickness
|
524 |
# Embodied carbon
|
525 |
embodied_carbon += material.embodied_carbon * material.density * thickness
|
526 |
# Cost
|
527 |
cost += material.price * thickness
|
|
|
|
|
528 |
|
529 |
r_value += R_SE # External surface resistance
|
530 |
u_value = 1.0 / r_value if r_value > 0 else 0.0
|
@@ -537,6 +586,8 @@ def calculate_construction_properties(layers: List[Dict[str, Any]], materials: D
|
|
537 |
else:
|
538 |
thermal_mass_category = "High"
|
539 |
|
|
|
|
|
540 |
return {
|
541 |
"u_value": u_value,
|
542 |
"r_value": r_value,
|
|
|
238 |
if category_str not in MaterialCategory.__members__:
|
239 |
st.error(f"Invalid category for material {material_name}: {library_material['category']}")
|
240 |
break
|
241 |
+
try:
|
242 |
+
new_material = Material(
|
243 |
+
name=new_mat_name,
|
244 |
+
category=MaterialCategory[category_str],
|
245 |
+
conductivity=library_material["thermal_properties"]["conductivity"],
|
246 |
+
density=library_material["thermal_properties"]["density"],
|
247 |
+
specific_heat=library_material["thermal_properties"]["specific_heat"],
|
248 |
+
default_thickness=library_material["thickness_range"]["default"],
|
249 |
+
embodied_carbon=library_material["embodied_carbon"],
|
250 |
+
absorptivity=library_material.get("absorptivity", 0.6),
|
251 |
+
price=library_material["cost"]["material"],
|
252 |
+
emissivity=library_material.get("emissivity", 0.9),
|
253 |
+
is_library=False
|
254 |
+
)
|
255 |
+
except Exception as e:
|
256 |
+
st.error(f"Failed to create material '{new_mat_name}': {str(e)}")
|
257 |
+
logger.error(f"Error creating material {new_mat_name}: {str(e)}")
|
258 |
+
break
|
259 |
success, message = material_library.add_project_material(new_material, st.session_state.project_data["materials"]["project"])
|
260 |
if not success:
|
261 |
st.error(f"Failed to copy material '{material_name}': {message}")
|
|
|
344 |
materials = get_available_materials()
|
345 |
material_objects = {name: m for name, m in materials.items() if isinstance(m, Material)}
|
346 |
if is_preview:
|
347 |
+
for name, mat_dict in st.session_state.project_data["materials"]["library"].items():
|
348 |
+
if name not in material_objects:
|
349 |
+
if "thermal_properties" not in mat_dict:
|
350 |
+
st.error(f"Material '{name}' is missing thermal properties")
|
351 |
+
logger.error(f"Missing thermal properties for material: {name}")
|
352 |
+
continue
|
353 |
+
category_str = mat_dict["category"].upper().replace("-", "_")
|
354 |
+
if category_str not in MaterialCategory.__members__:
|
355 |
+
st.error(f"Invalid category for material {name}: {mat_dict['category']}")
|
356 |
+
logger.error(f"Invalid category for material {name}: {mat_dict['category']}")
|
357 |
+
continue
|
358 |
+
try:
|
359 |
+
material_objects[name] = Material(
|
360 |
+
name=name,
|
361 |
+
category=MaterialCategory[category_str],
|
362 |
+
conductivity=mat_dict["thermal_properties"]["conductivity"],
|
363 |
+
density=mat_dict["thermal_properties"]["density"],
|
364 |
+
specific_heat=mat_dict["thermal_properties"]["specific_heat"],
|
365 |
+
default_thickness=mat_dict["thickness_range"]["default"],
|
366 |
+
embodied_carbon=mat_dict["embodied_carbon"],
|
367 |
+
absorptivity=mat_dict.get("absorptivity", 0.6),
|
368 |
+
price=mat_dict["cost"]["material"],
|
369 |
+
emissivity=mat_dict.get("emissivity", 0.9),
|
370 |
+
is_library=True
|
371 |
+
)
|
372 |
+
except Exception as e:
|
373 |
+
st.error(f"Failed to convert material '{name}' to Material object: {str(e)}")
|
374 |
+
logger.error(f"Error converting material {name}: {str(e)}")
|
375 |
+
continue
|
376 |
material_names = list(material_objects.keys())
|
377 |
|
378 |
if not material_names and not is_preview:
|
|
|
467 |
material_name = layer.get("material_name")
|
468 |
thickness = layer.get("thickness", 0.1)
|
469 |
if material_name in material_objects:
|
470 |
+
valid_layers.append({"material": material_objects[material_name], "thickness": thickness})
|
471 |
+
else:
|
472 |
+
st.warning(f"Material '{material_name}' not found in material objects.")
|
473 |
if valid_layers:
|
474 |
+
try:
|
475 |
+
r_total = R_SI
|
476 |
+
for layer in valid_layers:
|
477 |
+
if layer["material"].conductivity > 0:
|
478 |
+
r_total += layer["thickness"] / layer["material"].conductivity
|
479 |
+
else:
|
480 |
+
logger.warning(f"Invalid conductivity for material {layer['material'].name}: {layer['material'].conductivity}")
|
481 |
+
r_total += R_SE
|
482 |
+
u_value = 1.0 / r_total if r_total > 0 else 0.1
|
483 |
+
st.write(f"Calculated U-Value: {u_value:.3f} W/m虏路K")
|
484 |
+
except Exception as e:
|
485 |
+
st.error(f"Error calculating U-Value: {str(e)}")
|
486 |
+
logger.error(f"U-Value calculation error: {str(e)}")
|
487 |
else:
|
488 |
st.warning("No valid materials selected for U-Value calculation.")
|
489 |
else:
|
|
|
545 |
st.error(f"Failed to save construction: {message}")
|
546 |
except Exception as e:
|
547 |
st.error(f"Error saving construction: {str(e)}")
|
548 |
+
logger.error(f"Construction save error: {str(e)}")
|
549 |
|
550 |
def calculate_construction_properties(layers: List[Dict[str, Any]], materials: Dict[str, Any]) -> Dict[str, float]:
|
551 |
"""
|
|
|
564 |
# Thermal resistance
|
565 |
if material.conductivity > 0:
|
566 |
r_value += thickness / material.conductivity
|
567 |
+
else:
|
568 |
+
logger.warning(f"Invalid conductivity for material {material_name}: {material.conductivity}")
|
569 |
# Thermal mass
|
570 |
thermal_mass += material.density * material.specific_heat * thickness
|
571 |
# Embodied carbon
|
572 |
embodied_carbon += material.embodied_carbon * material.density * thickness
|
573 |
# Cost
|
574 |
cost += material.price * thickness
|
575 |
+
else:
|
576 |
+
logger.warning(f"Material {material_name} not found in materials dictionary")
|
577 |
|
578 |
r_value += R_SE # External surface resistance
|
579 |
u_value = 1.0 / r_value if r_value > 0 else 0.0
|
|
|
586 |
else:
|
587 |
thermal_mass_category = "High"
|
588 |
|
589 |
+
logger.debug(f"Calculated properties: U={u_value:.3f}, R={r_value:.3f}, Thermal Mass={thermal_mass:.1f}, Category={thermal_mass_category}")
|
590 |
+
|
591 |
return {
|
592 |
"u_value": u_value,
|
593 |
"r_value": r_value,
|