physics-adapter.js•22.6 kB
/**
* Enhanced Physics Adapter for Educational Content Generation
* @module content-generation/physics-adapter
* @description Specialized adapter for physics content with mathematical and scientific enhancements
* @version 5.0.0-alpha
*/
import { BaseAdapter } from './base-adapter.js';
export class PhysicsAdapter extends BaseAdapter {
constructor(config = {}) {
super({
...config,
subject: 'física',
enhancedFeatures: ['equations', 'calculations', 'diagrams', 'units']
});
// Initialize physics-specific capabilities
this.initializePhysicsCapabilities();
}
/**
* Initialize physics-specific enhancement modules
*/
initializePhysicsCapabilities() {
// Physics equation patterns and templates
this.equationPatterns = {
mechanics: {
velocity: 'v = Δx/Δt',
acceleration: 'a = Δv/Δt',
force: 'F = ma',
energy: 'E = ½mv²',
momentum: 'p = mv',
work: 'W = F·d',
power: 'P = W/t'
},
thermodynamics: {
ideal_gas: 'PV = nRT',
heat: 'Q = mcΔT',
efficiency: 'η = W/Q',
entropy: 'ΔS = Q/T'
},
electromagnetics: {
coulomb: 'F = kq₁q₂/r²',
ohm: 'V = IR',
power_electric: 'P = VI',
magnetic_force: 'F = qvB',
faraday: 'ε = -dΦ/dt'
},
waves: {
wave_equation: 'v = λf',
period: 'T = 1/f',
energy_wave: 'E = hf',
doppler: "f' = f(v ± vₒ)/(v ± vₛ)"
}
};
// Unit conversion system
this.unitConversions = {
length: {
'm': 1,
'km': 1000,
'cm': 0.01,
'mm': 0.001
},
time: {
's': 1,
'min': 60,
'h': 3600,
'ms': 0.001
},
mass: {
'kg': 1,
'g': 0.001,
't': 1000
},
force: {
'N': 1,
'kN': 1000,
'dyn': 1e-5
}
};
// Physics problem types
this.problemTypes = {
kinematics: ['motion', 'velocity', 'acceleration', 'trajectory'],
dynamics: ['force', 'friction', 'momentum', 'collision'],
energy: ['kinetic', 'potential', 'conservation', 'work'],
thermodynamics: ['heat', 'temperature', 'entropy', 'efficiency'],
waves: ['frequency', 'wavelength', 'interference', 'resonance'],
electricity: ['current', 'voltage', 'resistance', 'circuits'],
magnetism: ['field', 'flux', 'induction', 'magnetic_force']
};
// Physics diagram types
this.diagramTypes = {
force: 'Force diagrams and free body diagrams',
motion: 'Trajectory plots and motion graphs',
energy: 'Energy flow and transformation diagrams',
wave: 'Wave patterns and interference diagrams',
circuit: 'Electrical circuit schematics',
field: 'Electric and magnetic field representations'
};
}
/**
* Enhanced content generation with physics-specific features
* @param {Object} topicAnalysis - Result from analyzeTopic
* @param {Object} requirements - Content generation requirements
* @returns {Promise<Object>} Enhanced physics content
*/
async generateContent(topicAnalysis, requirements = {}) {
console.log('[PHYSICS-ADAPTER] Generating enhanced physics content for:', topicAnalysis.subject);
try {
// Generate base content first
const baseContent = await super.generateContent(topicAnalysis, requirements);
// Enhance with physics-specific content
const enhancedContent = await this.enhanceWithPhysicsContent(baseContent, topicAnalysis);
console.log('[PHYSICS-ADAPTER] Physics enhancement complete');
return enhancedContent;
} catch (error) {
console.error('[PHYSICS-ADAPTER] Enhanced content generation failed:', error);
throw new Error(`Physics content generation failed: ${error.message}`);
}
}
/**
* Enhance base content with physics-specific features
* @param {Object} baseContent - Base content from BaseAdapter
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Enhanced content
*/
async enhanceWithPhysicsContent(baseContent, topicAnalysis) {
const enhanced = { ...baseContent };
// Add physics metadata
enhanced.metadata.subject = 'física';
enhanced.metadata.enhancedFeatures = this.config.enhancedFeatures;
enhanced.metadata.physicsType = this.identifyPhysicsType(topicAnalysis);
// Enhance explanation with equations and calculations
if (enhanced.components.explanation) {
enhanced.components.explanation = await this.enhanceExplanationWithPhysics(
enhanced.components.explanation,
topicAnalysis
);
}
// Enhance examples with physics problems
if (enhanced.components.examples) {
enhanced.components.examples = await this.enhanceExamplesWithPhysics(
enhanced.components.examples,
topicAnalysis
);
}
// Enhance assessment with physics problems
if (enhanced.components.assessment) {
enhanced.components.assessment = await this.enhanceAssessmentWithPhysics(
enhanced.components.assessment,
topicAnalysis
);
}
// Add physics-specific components
enhanced.components.equations = await this.generateEquationsComponent(topicAnalysis);
enhanced.components.diagrams = await this.generateDiagramsComponent(topicAnalysis);
enhanced.components.calculations = await this.generateCalculationsComponent(topicAnalysis);
return enhanced;
}
/**
* Identify physics type from topic analysis
* @param {Object} topicAnalysis - Topic analysis result
* @returns {string} Physics type
*/
identifyPhysicsType(topicAnalysis) {
const { keywords, concepts } = topicAnalysis;
const allTerms = [...keywords, ...concepts].join(' ').toLowerCase();
// Check against physics problem types
for (const [type, terms] of Object.entries(this.problemTypes)) {
for (const term of terms) {
if (allTerms.includes(term)) {
return type;
}
}
}
// Default physics type based on common terms
if (allTerms.includes('força') || allTerms.includes('movimento')) return 'dynamics';
if (allTerms.includes('energia') || allTerms.includes('trabalho')) return 'energy';
if (allTerms.includes('onda') || allTerms.includes('frequência')) return 'waves';
if (allTerms.includes('calor') || allTerms.includes('temperatura')) return 'thermodynamics';
if (allTerms.includes('elétrico') || allTerms.includes('corrente')) return 'electricity';
return 'kinematics'; // Default to kinematics
}
/**
* Enhance explanation with physics content
* @param {Object} explanation - Base explanation component
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Enhanced explanation
*/
async enhanceExplanationWithPhysics(explanation, topicAnalysis) {
const enhanced = { ...explanation };
// Add physics principles
const physicsType = this.identifyPhysicsType(topicAnalysis);
const principles = this.getPhysicsPrinciples(physicsType);
// Enhance content with physics-specific information
enhanced.content += '\n\n**Princípios Físicos Fundamentais:**\n';
enhanced.content += principles.join('\n• ');
// Add mathematical formulation if applicable
const equations = this.getRelevantEquations(physicsType);
if (equations.length > 0) {
enhanced.content += '\n\n**Formulação Matemática:**\n';
enhanced.content += equations.map(eq => `• ${eq}`).join('\n');
}
// Add units and measurements
const units = this.getRelevantUnits(physicsType);
if (units.length > 0) {
enhanced.content += '\n\n**Unidades de Medida:**\n';
enhanced.content += units.map(unit => `• ${unit}`).join('\n');
}
return enhanced;
}
/**
* Enhance examples with physics problems
* @param {Object} examples - Base examples component
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Enhanced examples
*/
async enhanceExamplesWithPhysics(examples, topicAnalysis) {
const enhanced = { ...examples };
// Generate physics-specific examples
const physicsType = this.identifyPhysicsType(topicAnalysis);
const physicsExamples = this.generatePhysicsExamples(physicsType);
enhanced.examples = [...enhanced.examples, ...physicsExamples];
enhanced.content += '\n\n**Exemplos de Problemas de Física:**\n';
enhanced.content += physicsExamples.map((ex, i) => `${i + 1}. ${ex}`).join('\n\n');
return enhanced;
}
/**
* Enhance assessment with physics problems
* @param {Object} assessment - Base assessment component
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Enhanced assessment
*/
async enhanceAssessmentWithPhysics(assessment, topicAnalysis) {
const enhanced = { ...assessment };
// Add physics-specific questions
const physicsType = this.identifyPhysicsType(topicAnalysis);
const physicsQuestions = this.generatePhysicsQuestions(physicsType, topicAnalysis);
enhanced.questions = [...enhanced.questions, ...physicsQuestions];
return enhanced;
}
/**
* Generate equations component
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Equations component
*/
async generateEquationsComponent(topicAnalysis) {
const physicsType = this.identifyPhysicsType(topicAnalysis);
const equations = this.getRelevantEquations(physicsType);
return {
type: 'equations',
title: 'Equações Fundamentais',
content: 'As equações a seguir são fundamentais para compreender e resolver problemas relacionados ao tópico.',
equations: equations,
physicsType: physicsType,
duration: '5-8 minutos'
};
}
/**
* Generate diagrams component
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Diagrams component
*/
async generateDiagramsComponent(topicAnalysis) {
const physicsType = this.identifyPhysicsType(topicAnalysis);
const diagramSuggestions = this.getDiagramSuggestions(physicsType);
return {
type: 'diagrams',
title: 'Diagramas e Representações Visuais',
content: 'Representações visuais são essenciais para compreender conceitos físicos.',
suggestions: diagramSuggestions,
physicsType: physicsType,
duration: '8-12 minutos'
};
}
/**
* Generate calculations component
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Promise<Object>} Calculations component
*/
async generateCalculationsComponent(topicAnalysis) {
const physicsType = this.identifyPhysicsType(topicAnalysis);
const calculationSteps = this.getCalculationSteps(physicsType);
return {
type: 'calculations',
title: 'Métodos de Cálculo',
content: 'Passos sistemáticos para resolver problemas físicos.',
steps: calculationSteps,
physicsType: physicsType,
duration: '10-15 minutos'
};
}
/**
* Get physics principles for a given type
* @param {string} physicsType - Type of physics
* @returns {Array} Physics principles
*/
getPhysicsPrinciples(physicsType) {
const principles = {
kinematics: [
'Movimento é a mudança de posição em relação ao tempo',
'Velocidade é a taxa de variação da posição',
'Aceleração é a taxa de variação da velocidade',
'Equações cinemáticas descrevem movimento uniformemente acelerado'
],
dynamics: [
'Primeira Lei de Newton: Lei da Inércia',
'Segunda Lei de Newton: F = ma',
'Terceira Lei de Newton: Ação e Reação',
'Conservação do momento linear'
],
energy: [
'Energia não pode ser criada nem destruída',
'Energia cinética: energia do movimento',
'Energia potencial: energia armazenada',
'Trabalho é transferência de energia'
],
thermodynamics: [
'Primeira Lei: Conservação de energia',
'Segunda Lei: Entropia sempre aumenta',
'Terceira Lei: Entropia zero no zero absoluto',
'Lei Zero: Equilíbrio térmico'
],
waves: [
'Ondas transportam energia sem transportar matéria',
'Frequência e período são inversamente proporcionais',
'Velocidade da onda depende do meio',
'Princípio da superposição'
],
electricity: [
'Lei de Coulomb: força entre cargas',
'Lei de Ohm: relação V-I-R',
'Conservação da carga elétrica',
'Leis de Kirchhoff para circuitos'
]
};
return principles[physicsType] || principles.kinematics;
}
/**
* Get relevant equations for physics type
* @param {string} physicsType - Type of physics
* @returns {Array} Relevant equations
*/
getRelevantEquations(physicsType) {
const typeMapping = {
kinematics: 'mechanics',
dynamics: 'mechanics',
energy: 'mechanics',
thermodynamics: 'thermodynamics',
waves: 'waves',
electricity: 'electromagnetics'
};
const category = typeMapping[physicsType] || 'mechanics';
const equations = this.equationPatterns[category] || {};
return Object.entries(equations).map(([name, equation]) =>
`${name.replace('_', ' ')}: ${equation}`
);
}
/**
* Get relevant units for physics type
* @param {string} physicsType - Type of physics
* @returns {Array} Relevant units
*/
getRelevantUnits(physicsType) {
const units = {
kinematics: ['metro (m)', 'segundo (s)', 'metro por segundo (m/s)', 'metro por segundo² (m/s²)'],
dynamics: ['newton (N)', 'quilograma (kg)', 'metro por segundo² (m/s²)', 'pascal (Pa)'],
energy: ['joule (J)', 'watt (W)', 'quilograma (kg)', 'metro por segundo (m/s)'],
thermodynamics: ['kelvin (K)', 'joule (J)', 'pascal (Pa)', 'metro³ (m³)'],
waves: ['hertz (Hz)', 'metro (m)', 'segundo (s)', 'joule (J)'],
electricity: ['ampere (A)', 'volt (V)', 'ohm (Ω)', 'coulomb (C)', 'watt (W)']
};
return units[physicsType] || units.kinematics;
}
/**
* Generate physics-specific examples
* @param {string} physicsType - Type of physics
* @returns {Array} Physics examples
*/
generatePhysicsExamples(physicsType) {
const examples = {
kinematics: [
'Um carro acelera de 0 a 60 km/h em 8 segundos. Calcule a aceleração.',
'Uma bola é lançada verticalmente para cima com velocidade inicial de 20 m/s. Determine a altura máxima.',
'Um projétil é lançado com ângulo de 45° e velocidade inicial de 30 m/s.'
],
dynamics: [
'Uma caixa de 10 kg é empurrada sobre uma superfície com coeficiente de atrito 0,3.',
'Dois carros colidem frontalmente: um de 1000 kg a 20 m/s e outro de 1500 kg a 15 m/s.',
'Um bloco de 5 kg está sobre um plano inclinado de 30°.'
],
energy: [
'Um pêndulo simples de 2 m de comprimento oscila com amplitude de 10°.',
'Uma mola com constante k=100 N/m é comprimida 0,2 m.',
'Um esquiador desce uma rampa de 50 m de altura.'
],
thermodynamics: [
'Um gás ideal passa por um processo isotérmico de 1 L para 2 L.',
'Uma máquina térmica opera entre reservatórios a 400 K e 300 K.',
'100 g de água a 20°C são aquecidos até 80°C.'
],
waves: [
'Uma onda sonora de frequência 440 Hz se propaga no ar.',
'Interferência construtiva entre duas ondas de mesma amplitude.',
'Efeito Doppler: ambulância se aproximando a 30 m/s.'
],
electricity: [
'Circuito em série com resistores de 10 Ω, 20 Ω e 30 Ω.',
'Duas cargas de +2 μC e -3 μC separadas por 0,5 m.',
'Gerador de 12 V alimenta uma lâmpada de resistência 6 Ω.'
]
};
return examples[physicsType] || examples.kinematics;
}
/**
* Generate physics-specific questions
* @param {string} physicsType - Type of physics
* @param {Object} topicAnalysis - Topic analysis result
* @returns {Array} Physics questions
*/
generatePhysicsQuestions(physicsType, topicAnalysis) {
const questions = [
{
type: 'multiple_choice',
question: `Em problemas de ${physicsType}, qual é a grandeza física fundamental?`,
options: [
'Força',
'Energia',
'Momento',
'Todas as anteriores'
],
correct: 3,
explanation: 'Todas as grandezas são fundamentais dependendo do contexto do problema.'
},
{
type: 'calculation',
question: `Resolva um problema típico de ${physicsType} aplicando as equações apropriadas.`,
requiredSteps: ['Identificar dados', 'Escolher equação', 'Calcular', 'Verificar unidades'],
physicsType: physicsType
},
{
type: 'conceptual',
question: `Explique o princípio físico fundamental que governa ${topicAnalysis.subject}.`,
keywords: ['princípio', 'fundamento', 'lei física', 'aplicação'],
expectedLength: 'medium'
}
];
return questions;
}
/**
* Get diagram suggestions for physics type
* @param {string} physicsType - Type of physics
* @returns {Array} Diagram suggestions
*/
getDiagramSuggestions(physicsType) {
const suggestions = {
kinematics: [
'Gráfico posição vs tempo',
'Gráfico velocidade vs tempo',
'Diagrama de trajetória',
'Representação vetorial do movimento'
],
dynamics: [
'Diagrama de corpo livre',
'Diagrama de forças',
'Representação de sistemas dinâmicos',
'Diagrama de momento'
],
energy: [
'Diagrama de conservação de energia',
'Representação de transformações energéticas',
'Gráfico energia vs posição',
'Diagrama de fluxo de energia'
],
thermodynamics: [
'Diagrama P-V (pressão-volume)',
'Ciclo termodinâmico',
'Diagrama de estados',
'Representação de processos térmicos'
],
waves: [
'Gráfico onda vs tempo',
'Padrão de interferência',
'Diagrama de ondas estacionárias',
'Representação do espectro'
],
electricity: [
'Esquema de circuito elétrico',
'Diagrama de campo elétrico',
'Representação de linhas equipotenciais',
'Diagrama de distribuição de cargas'
]
};
return suggestions[physicsType] || suggestions.kinematics;
}
/**
* Get calculation steps for physics type
* @param {string} physicsType - Type of physics
* @returns {Array} Calculation steps
*/
getCalculationSteps(physicsType) {
const steps = {
kinematics: [
'1. Identificar as grandezas conhecidas e desconhecidas',
'2. Escolher o sistema de referência apropriado',
'3. Selecionar a equação cinemática adequada',
'4. Substituir os valores conhecidos',
'5. Resolver a equação matematicamente',
'6. Verificar unidades e razoabilidade do resultado'
],
dynamics: [
'1. Desenhar o diagrama de corpo livre',
'2. Identificar todas as forças atuantes',
'3. Aplicar as Leis de Newton',
'4. Definir sistema de coordenadas',
'5. Resolver o sistema de equações',
'6. Verificar o resultado fisicamente'
],
energy: [
'1. Identificar os tipos de energia envolvidos',
'2. Definir o sistema e suas fronteiras',
'3. Aplicar o princípio de conservação',
'4. Calcular energias inicial e final',
'5. Considerar perdas ou ganhos de energia',
'6. Verificar conservação total'
]
};
return steps[physicsType] || steps.kinematics;
}
/**
* Enhanced topic analysis for physics content
* @param {string} topicDescription - Natural description of the physics topic
* @returns {Promise<Object>} Enhanced physics topic analysis
*/
async analyzeTopic(topicDescription) {
// Get base analysis
const baseAnalysis = await super.analyzeTopic(topicDescription);
// Add physics-specific analysis
const physicsType = this.identifyPhysicsType(baseAnalysis);
const mathematicalLevel = this.assessMathematicalLevel(topicDescription);
const experimentalAspects = this.identifyExperimentalAspects(topicDescription);
return {
...baseAnalysis,
physicsType: physicsType,
mathematicalLevel: mathematicalLevel,
experimentalAspects: experimentalAspects,
applicableEquations: this.getRelevantEquations(physicsType),
suggestedDiagrams: this.getDiagramSuggestions(physicsType),
unitSystem: this.getRelevantUnits(physicsType)
};
}
/**
* Assess mathematical level required
* @param {string} topicDescription - Topic description
* @returns {string} Mathematical level
*/
assessMathematicalLevel(topicDescription) {
const text = topicDescription.toLowerCase();
if (text.includes('integral') || text.includes('derivada') || text.includes('cálculo')) {
return 'advanced';
}
if (text.includes('equação') || text.includes('função') || text.includes('trigonometria')) {
return 'intermediate';
}
return 'basic';
}
/**
* Identify experimental aspects
* @param {string} topicDescription - Topic description
* @returns {Array} Experimental aspects
*/
identifyExperimentalAspects(topicDescription) {
const text = topicDescription.toLowerCase();
const aspects = [];
if (text.includes('experimento') || text.includes('laboratório')) {
aspects.push('laboratory');
}
if (text.includes('medida') || text.includes('medição')) {
aspects.push('measurement');
}
if (text.includes('erro') || text.includes('incerteza')) {
aspects.push('uncertainty');
}
if (text.includes('gráfico') || text.includes('dados')) {
aspects.push('data_analysis');
}
return aspects;
}
}
// Factory function for creating PhysicsAdapter instances
export function createPhysicsAdapter(config = {}) {
return new PhysicsAdapter(config);
}