增加扩胞逻辑
This commit is contained in:
@@ -64,9 +64,10 @@ class StructureInfo:
|
||||
is_binary_compound: bool = False
|
||||
|
||||
# 共占位详细分析(新增)
|
||||
cation_has_partial_occupancy: bool = False # 目标阳离子共占位
|
||||
anion_has_partial_occupancy: bool = False # 阴离子共占位
|
||||
other_has_partial_occupancy: bool = False # 其他元素共占位(需扩胞)
|
||||
cation_with_vacancy: bool = False # Li与空位共占位(不需处理)
|
||||
cation_with_other_cation: bool = False # Li与其他阳离子共占位(需扩胞)
|
||||
anion_has_partial_occupancy: bool = False # 阴离子共占位
|
||||
other_has_partial_occupancy: bool = False # 其他元素共占位(需扩胞)
|
||||
expansion_info: ExpansionInfo = field(default_factory=ExpansionInfo)
|
||||
|
||||
# 可处理性
|
||||
@@ -218,14 +219,17 @@ class StructureInspector:
|
||||
continue
|
||||
return None
|
||||
|
||||
# 在 StructureInspector 类中,替换 _analyze_partial_occupancy 方法
|
||||
|
||||
def _analyze_partial_occupancy(self, structure: Structure, info: StructureInfo):
|
||||
"""
|
||||
分析共占位情况(核心逻辑)
|
||||
分析共占位情况(修正版)
|
||||
|
||||
关键规则:
|
||||
- 目标阳离子(Li)的共占位 → 不可处理
|
||||
- 阴离子的共占位 → 需要扩胞,但通常不处理
|
||||
- 其他阳离子的共占位 → 需要扩胞处理
|
||||
- Li与空位共占位 → 不需要处理(cation_with_vacancy)
|
||||
- Li与其他阳离子共占位 → 需要扩胞(cation_with_other_cation)
|
||||
- 阴离子共占位 → 通常不处理
|
||||
- 其他阳离子共占位 → 需要扩胞
|
||||
"""
|
||||
occupancy_dict = defaultdict(list) # {occupation: [site_indices]}
|
||||
occupancy_elements = {} # {occupation: [elements]}
|
||||
@@ -234,60 +238,118 @@ class StructureInspector:
|
||||
site_species = site.species
|
||||
species_string = str(site.species)
|
||||
|
||||
# 检查是否有多个物种占据同一位点
|
||||
if len(site_species) > 1:
|
||||
info.has_partial_occupancy = True
|
||||
# 提取各元素及其占据率
|
||||
species_occu = {} # {element: occupancy}
|
||||
for sp, occu in site_species.items():
|
||||
elem = sp.symbol if hasattr(sp, 'symbol') else str(sp)
|
||||
elem = self._get_element_from_species_string(elem)
|
||||
if elem:
|
||||
species_occu[elem] = occu
|
||||
|
||||
# 提取各元素符号
|
||||
elements_at_site = []
|
||||
for sp in site_species.keys():
|
||||
elem = sp.symbol if hasattr(sp, 'symbol') else str(sp)
|
||||
elem = self._get_element_from_species_string(elem)
|
||||
if elem:
|
||||
elements_at_site.append(elem)
|
||||
total_occupancy = sum(species_occu.values())
|
||||
elements_at_site = list(species_occu.keys())
|
||||
|
||||
# 判断是否涉及目标阳离子
|
||||
if self.target_cation in elements_at_site:
|
||||
info.cation_has_partial_occupancy = True
|
||||
# 检查是否有部分占据
|
||||
has_partial = any(occu < 1.0 for occu in species_occu.values()) or len(species_occu) > 1
|
||||
|
||||
if not has_partial:
|
||||
continue
|
||||
|
||||
info.has_partial_occupancy = True
|
||||
|
||||
# 判断Li的共占位情况
|
||||
if self.target_cation in elements_at_site:
|
||||
li_occu = species_occu.get(self.target_cation, 0)
|
||||
other_elements = [e for e in elements_at_site if e != self.target_cation]
|
||||
|
||||
if not other_elements and li_occu < 1.0:
|
||||
# Li与空位共占位(Li占据率<1,但没有其他元素)
|
||||
info.cation_with_vacancy = True
|
||||
elif other_elements:
|
||||
# Li与其他元素共占位
|
||||
other_are_anions = all(e in self.target_anions for e in other_elements)
|
||||
if other_are_anions:
|
||||
# Li与阴离子共占位(罕见,标记为阴离子共占位)
|
||||
info.anion_has_partial_occupancy = True
|
||||
else:
|
||||
# Li与其他阳离子共占位 → 需要扩胞
|
||||
info.cation_with_other_cation = True
|
||||
|
||||
# 记录需要扩胞的占据率(取非Li元素的占据率)
|
||||
for elem in other_elements:
|
||||
if elem not in self.target_anions:
|
||||
occu = species_occu.get(elem, 0)
|
||||
if occu > 0 and occu < 1.0:
|
||||
occupancy_dict[occu].append(i)
|
||||
occupancy_elements[occu] = elements_at_site
|
||||
else:
|
||||
# 不涉及Li的位点
|
||||
# 判断是否涉及阴离子
|
||||
if any(elem in self.target_anions for elem in elements_at_site):
|
||||
info.anion_has_partial_occupancy = True
|
||||
|
||||
# 判断是否涉及其他元素(需要扩胞处理的情况)
|
||||
other_elements = [e for e in elements_at_site
|
||||
if e != self.target_cation and e not in self.target_anions]
|
||||
if other_elements:
|
||||
else:
|
||||
# 其他阳离子的共占位 → 需要扩胞
|
||||
info.other_has_partial_occupancy = True
|
||||
|
||||
# 获取占据率(取非目标阳离子的占据率)
|
||||
occu = self._get_occupancy_from_species_string(
|
||||
species_string,
|
||||
self.target_cation_variants
|
||||
)
|
||||
if occu is not None and occu != 1.0:
|
||||
occupancy_dict[occu].append(i)
|
||||
occupancy_elements[occu] = elements_at_site
|
||||
|
||||
# 检查单一物种的部分占据
|
||||
for specie, occupancy in site_species.items():
|
||||
if occupancy < 1.0:
|
||||
info.has_partial_occupancy = True
|
||||
elem = specie.symbol if hasattr(specie, 'symbol') else str(specie)
|
||||
elem = self._get_element_from_species_string(elem)
|
||||
|
||||
if elem == self.target_cation:
|
||||
info.cation_has_partial_occupancy = True
|
||||
elif elem in self.target_anions:
|
||||
info.anion_has_partial_occupancy = True
|
||||
else:
|
||||
info.other_has_partial_occupancy = True
|
||||
occupancy_dict[occupancy].append(i)
|
||||
occupancy_elements[occupancy] = [elem]
|
||||
# 获取占据率
|
||||
for elem, occu in species_occu.items():
|
||||
if occu > 0 and occu < 1.0:
|
||||
occupancy_dict[occu].append(i)
|
||||
occupancy_elements[occu] = elements_at_site
|
||||
break # 只记录一次
|
||||
|
||||
# 计算扩胞信息
|
||||
self._calculate_expansion_info(info, occupancy_dict, occupancy_elements)
|
||||
|
||||
def _evaluate_processability(self, info: StructureInfo):
|
||||
"""评估可处理性(修正版)"""
|
||||
skip_reasons = []
|
||||
|
||||
if not info.is_valid:
|
||||
skip_reasons.append("无法解析CIF文件")
|
||||
|
||||
if not info.contains_target_cation:
|
||||
skip_reasons.append(f"不含{self.target_cation}")
|
||||
|
||||
if info.anion_mode == "none":
|
||||
skip_reasons.append("不含目标阴离子")
|
||||
|
||||
if info.is_binary_compound:
|
||||
skip_reasons.append("二元化合物")
|
||||
|
||||
if info.has_radioactive_elements:
|
||||
skip_reasons.append("含放射性元素")
|
||||
|
||||
# Li与空位共占位 → 不需要处理(不加入skip_reasons)
|
||||
# info.cation_with_vacancy 不影响可处理性
|
||||
|
||||
# Li与其他阳离子共占位 → 需要扩胞(如果扩胞因子合理则可处理)
|
||||
if info.cation_with_other_cation:
|
||||
if info.expansion_info.can_expand:
|
||||
info.needs_expansion = True
|
||||
else:
|
||||
skip_reasons.append(f"{self.target_cation}与其他阳离子共占位且{info.expansion_info.skip_reason}")
|
||||
|
||||
# 阴离子共占位 → 不处理
|
||||
if info.anion_has_partial_occupancy:
|
||||
skip_reasons.append("阴离子存在共占位")
|
||||
|
||||
if info.has_water_molecule:
|
||||
skip_reasons.append("含水分子")
|
||||
|
||||
# 其他阳离子共占位(不涉及Li)→ 需要扩胞
|
||||
if info.other_has_partial_occupancy:
|
||||
if info.expansion_info.can_expand:
|
||||
info.needs_expansion = True
|
||||
else:
|
||||
skip_reasons.append(info.expansion_info.skip_reason)
|
||||
|
||||
if skip_reasons:
|
||||
info.can_process = False
|
||||
info.skip_reason = "; ".join(skip_reasons)
|
||||
else:
|
||||
info.can_process = True
|
||||
|
||||
def _calculate_expansion_info(
|
||||
self,
|
||||
info: StructureInfo,
|
||||
|
||||
Reference in New Issue
Block a user